Skip to content

Commit

Permalink
Merge pull request #1 from franklin-ai/ros-enhancements-fixed-renamed…
Browse files Browse the repository at this point in the history
…-many-table

Fixes issue with many to many relationship not respecting renamed tables
  • Loading branch information
joaommartins authored Feb 20, 2023
2 parents a11e7eb + 65973fc commit 903db31
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 15 deletions.
2 changes: 1 addition & 1 deletion butane/tests/common/blog.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use butane::prelude::*;
use butane::{dataresult, model};
use butane::{db::Connection, ForeignKey, Many, ObjectState};
use chrono::{naive::NaiveDateTime, offset::Utc};
use chrono::{NaiveDateTime, Utc};

#[model]
#[derive(Debug, Eq, PartialEq)]
Expand Down
1 change: 1 addition & 0 deletions butane/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ macro_rules! maketest {
let backend = butane::db::get_backend(&stringify!($backend)).expect("Could not find backend");
let $dataname = $crate::common::[<$backend _setup>]();
eprintln!("connecting to {}", &$connstr);
println!("\nWe're now running {}\n", &stringify!($fname));
let mut conn = backend.connect(&$connstr).expect("Could not connect backend");
$crate::common::setup_db(backend, &mut conn);
$fname(conn);
Expand Down
31 changes: 31 additions & 0 deletions butane/tests/many.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ impl AutoPkWithMany {
}
}

#[model]
#[table = "renamed_many_table"]
struct RenamedAutoPkWithMany {
#[auto]
id: i64,
tags: Many<Tag>,
items: Many<AutoItem>,
}
impl RenamedAutoPkWithMany {
fn new() -> Self {
RenamedAutoPkWithMany {
id: -1,
tags: Many::default(),
items: Many::default(),
state: ObjectState::default(),
}
}
}

#[model]
struct AutoItem {
#[auto]
Expand Down Expand Up @@ -113,3 +132,15 @@ fn cant_add_unsaved_to_many(_conn: Connection) {
.expect_err("unexpectedly not error");
}
testall!(cant_add_unsaved_to_many);

fn can_add_to_many_with_custom_table_name(conn: Connection) {
let mut obj = RenamedAutoPkWithMany::new();
obj.tags.add(&create_tag(&conn, "blue")).unwrap();
obj.tags.add(&create_tag(&conn, "red")).unwrap();
obj.save(&conn).unwrap();

let obj = RenamedAutoPkWithMany::get(&conn, obj.id).unwrap();
let tags = obj.tags.load(&conn).unwrap();
assert_eq!(tags.count(), 2);
}
testall!(can_add_to_many_with_custom_table_name);
24 changes: 14 additions & 10 deletions butane_core/src/codegen/dbobj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
let numdbfields = fields(ast_struct).filter(|f| is_row_field(f)).count();
let many_save: TokenStream2 = fields(ast_struct).filter(|f| is_many_to_many(f)).map(|f| {
let ident = f.ident.clone().expect("Fields must be named for butane");
let many_table_lit = many_table_lit(ast_struct, f);
let many_table_lit = many_table_lit(ast_struct, f, config);
let pksqltype =
quote!(<<Self as butane::DataObject>::PKType as butane::FieldType>::SQLTYPE);
// Save needs to ensure_initialized
Expand All @@ -52,7 +52,7 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
let values: Vec<TokenStream2> = push_values(ast_struct, |_| true);
let values_no_pk: Vec<TokenStream2> = push_values(ast_struct, |f: &Field| f != &pk_field);

let dataresult = impl_dataresult(ast_struct, tyname);
let dataresult = impl_dataresult(ast_struct, tyname, config);
quote!(
#dataresult
impl butane::DataObject for #tyname {
Expand Down Expand Up @@ -137,7 +137,7 @@ pub fn impl_dbobject(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
)
}

pub fn impl_dataresult(ast_struct: &ItemStruct, dbo: &Ident) -> TokenStream2 {
pub fn impl_dataresult(ast_struct: &ItemStruct, dbo: &Ident, config: &Config) -> TokenStream2 {
let tyname = &ast_struct.ident;
let numdbfields = fields(ast_struct).filter(|f| is_row_field(f)).count();
let rows = rows_for_from(ast_struct);
Expand All @@ -151,7 +151,7 @@ pub fn impl_dataresult(ast_struct: &ItemStruct, dbo: &Ident) -> TokenStream2 {
.ident
.clone()
.expect("Fields must be named for butane");
let many_table_lit = many_table_lit(ast_struct, f);
let many_table_lit = many_table_lit(ast_struct, f, config);
let pksqltype = quote!(<<Self as butane::DataObject>::PKType as butane::FieldType>::SQLTYPE);
quote!(obj.#ident.ensure_init(#many_table_lit, butane::ToSql::to_sql(obj.pk()), #pksqltype);)
}).collect();
Expand Down Expand Up @@ -203,13 +203,13 @@ fn make_tablelit(config: &Config, tyname: &Ident) -> LitStr {
}
}

pub fn add_fieldexprs(ast_struct: &ItemStruct) -> TokenStream2 {
pub fn add_fieldexprs(ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
let tyname = &ast_struct.ident;
let vis = &ast_struct.vis;
let fieldexprs: Vec<TokenStream2> = fields(ast_struct)
.map(|f| {
if is_many_to_many(f) {
fieldexpr_func_many(f, ast_struct)
fieldexpr_func_many(f, ast_struct, config)
} else {
fieldexpr_func_regular(f, ast_struct)
}
Expand Down Expand Up @@ -247,10 +247,10 @@ fn fieldexpr_func_regular(f: &Field, ast_struct: &ItemStruct) -> TokenStream2 {
)
}

fn fieldexpr_func_many(f: &Field, ast_struct: &ItemStruct) -> TokenStream2 {
fn fieldexpr_func_many(f: &Field, ast_struct: &ItemStruct, config: &Config) -> TokenStream2 {
let tyname = &ast_struct.ident;
let fty = get_foreign_type_argument(&f.ty, "Many").expect("Many field misdetected");
let many_table_lit = many_table_lit(ast_struct, f);
let many_table_lit = many_table_lit(ast_struct, f, config);
fieldexpr_func(
f,
ast_struct,
Expand Down Expand Up @@ -342,12 +342,16 @@ where
.collect()
}

fn many_table_lit(ast_struct: &ItemStruct, field: &Field) -> LitStr {
let tyname = &ast_struct.ident;
fn many_table_lit(ast_struct: &ItemStruct, field: &Field, config: &Config) -> LitStr {
let ident = field
.ident
.clone()
.expect("Fields must be named for butane");
let binding = ast_struct.ident.to_string();
let tyname = match &config.table_name {
Some(s) => s,
None => &binding,
};
make_lit(&format!("{}_{}_Many", &tyname, &ident))
}

Expand Down
6 changes: 4 additions & 2 deletions butane_core/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ where
migration::write_table_to_disk(ms, &ast_struct, &config).unwrap();

let impltraits = dbobj::impl_dbobject(&ast_struct, &config);
let fieldexprs = dbobj::add_fieldexprs(&ast_struct);
let fieldexprs = dbobj::add_fieldexprs(&ast_struct, &config);

let fields: Punctuated<Field, syn::token::Comma> =
match remove_helper_field_attributes(&mut ast_struct.fields) {
Expand Down Expand Up @@ -81,7 +81,9 @@ where
pub fn dataresult(args: TokenStream2, input: TokenStream2) -> TokenStream2 {
let dbo: Ident = syn::parse2(args)
.expect("Model type must be specified as argument to dataresult attribute");

let mut ast_struct: ItemStruct = syn::parse2(input).unwrap();
let config: dbobj::Config = config_from_attributes(&ast_struct);

// Filter out our helper attributes
let attrs: Vec<Attribute> = filter_helper_attributes(&ast_struct);
Expand All @@ -94,7 +96,7 @@ pub fn dataresult(args: TokenStream2, input: TokenStream2) -> TokenStream2 {

let vis = &ast_struct.vis;

let impltraits = dbobj::impl_dataresult(&ast_struct, &dbo);
let impltraits = dbobj::impl_dataresult(&ast_struct, &dbo, &config);

let fields = match remove_helper_field_attributes(&mut ast_struct.fields) {
Ok(fields) => &fields.named,
Expand Down
3 changes: 1 addition & 2 deletions butane_core/src/many.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ fn default_oc<T>() -> OnceCell<Vec<T>> {
///
/// Creates a new table with columns "owner" and "has" If type T has a
/// many-to-many relationship with U, owner type is T::PKType, has is
/// U::PKType. Table name is T_ManyToMany_foo where foo is the name of
/// U::PKType. Table name is T_foo_Many where foo is the name of
/// the Many field
//
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Many<T>
where
Expand Down

0 comments on commit 903db31

Please sign in to comment.