add sync function

This commit is contained in:
mxhagen 2024-12-09 14:13:07 +01:00
parent d98570d50c
commit f38d9a6df2
2 changed files with 29 additions and 3 deletions

View File

@ -4,8 +4,6 @@ use syn::{parse_macro_input, Data, DeriveInput, Fields};
// TODO: wrap functions in a trait // TODO: wrap functions in a trait
// TODO: add sync function (set fields of self by querying db)
// TODO: doc comments // TODO: doc comments
#[proc_macro_derive(Table)] #[proc_macro_derive(Table)]
@ -126,7 +124,7 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
); );
let update_fn = quote! { let update_fn = quote! {
pub fn update(&mut self, conn: &rusqlite::Connection) -> rusqlite::Result<bool> pub fn update(&self, conn: &rusqlite::Connection) -> rusqlite::Result<bool>
where #(#to_sql_trait_bounds),* where #(#to_sql_trait_bounds),*
{ {
if self.id.is_none() { if self.id.is_none() {
@ -138,6 +136,22 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
}; };
let sync_fn = quote! {
pub fn sync(&mut self, conn: &rusqlite::Connection) -> rusqlite::Result<bool>
where #(#from_sql_trait_bounds),*
{
if self.id.is_none() {
return Ok(false);
}
match #struct_name::get_by_id(conn, self.id.unwrap())? {
Some(person) => *self = person,
_ => return Ok(false),
};
Ok(true)
}
};
let get_by_id_fn = quote! { let get_by_id_fn = quote! {
pub fn get_by_id(conn: &rusqlite::Connection, id: i64) -> rusqlite::Result<Option<Self>> pub fn get_by_id(conn: &rusqlite::Connection, id: i64) -> rusqlite::Result<Option<Self>>
where where
@ -197,6 +211,7 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
#insert_fn #insert_fn
#upsert_fn #upsert_fn
#update_fn #update_fn
#sync_fn
#get_by_id_fn #get_by_id_fn
#delete_fn #delete_fn
#delete_by_id_fn #delete_by_id_fn

View File

@ -87,11 +87,22 @@ fn test_table_derive_macro() {
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work"); let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
assert_eq!(larry_copy, Some(larry.clone()), "Retrieving upserted row should give an identical row"); assert_eq!(larry_copy, Some(larry.clone()), "Retrieving upserted row should give an identical row");
conn.execute("UPDATE Person SET (age) = (27) WHERE id = ?1", [larry_id])
.expect("Explicit Sqlite statement (not a library test) failed");
let found = larry.sync(&conn).expect("Syncing struct to existing row should succeed");
assert!(found, "Row should have been found");
assert_eq!(larry.age, 27, "Syncing struct to edited table row should work");
Person::drop_table(&conn).expect("Dropping table should work"); Person::drop_table(&conn).expect("Dropping table should work");
Person::drop_table(&conn).expect_err("Dropping previously dropped table should err"); Person::drop_table(&conn).expect_err("Dropping previously dropped table should err");
let exists: bool = conn.query_row("SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type='table' AND name='Person');", [], |row| row.get(0)).expect("Explicit Sqlite statement (not a library test) failed");
assert!(!exists, "Deleted table should not exist anymore but does");
} }
// TODO: implement compile-error test(s) -- perhaps with `trybuild`? // TODO: implement compile-error test(s) -- perhaps with `trybuild`?
// //
// #[test] // #[test]