make update fn signature more straightforward

This commit is contained in:
mxhagen 2024-12-11 22:30:08 +01:00
parent 109f6a5a70
commit 84efaaad3f
4 changed files with 18 additions and 15 deletions

2
Cargo.lock generated
View File

@ -118,7 +118,7 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "squail"
version = "0.1.1"
version = "0.1.2"
dependencies = [
"rusqlite",
"squail-macros",

View File

@ -1,6 +1,6 @@
[package]
name = "squail"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
[dependencies]

View File

@ -3,7 +3,9 @@ use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_macro_input, Data, DeriveInput, Fields};
// TODO: wrap functions in a trait? would probably use the other crate
// TODO: wrap functions in a trait? would probably use the other (main) crate
// TODO: own error enum (for update). also use the other (main) crate for this
#[proc_macro_derive(Table)]
@ -116,10 +118,10 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
match self.id {
None => self.insert(conn),
Some(id) => {
if !self.update(conn)? {
return self.insert(conn);
match self.update(conn) {
Ok(_) => return Ok(id),
Err(_) => return self.insert(conn),
}
Ok(id)
},
}
}
@ -136,19 +138,21 @@ pub fn derive_table(input: TokenStream) -> TokenStream {
let update_fn = quote! {
/// Update a table row using the calling struct instance.
///
/// If the row does not yet exist, this fails.
/// A version that inserts a new row instead also exists. See `update_or_insert`.
/// If `id` is `None`, this fails with `InvalidQuery`.
/// If the row does not exist, this fails with `QueryReturnedNoRows`.
///
/// Result contains `true` if a row was updated.
pub fn update(&self, conn: &rusqlite::Connection) -> rusqlite::Result<bool>
/// A version that inserts a new row instead also exists. See `update_or_insert`.
pub fn update(&self, conn: &rusqlite::Connection) -> rusqlite::Result<()>
where #(#to_sql_trait_bounds),*
{
if self.id.is_none() {
// TODO: bad design, should probably fail instead
return Ok(false);
return Err(rusqlite::Error::InvalidQuery)
}
let updated_count = conn.execute(#update_sql, rusqlite::params![#(#field_accessors),*])?;
Ok(updated_count > 0)
match updated_count {
0 => Err(rusqlite::Error::QueryReturnedNoRows),
_ => Ok(()),
}
}
};

View File

@ -67,8 +67,7 @@ fn test_table_derive_macro() {
.expect("After (mutable) insertion, id should not be None");
larry.age += 1;
let updated_something = larry.update(&conn).expect("Updating should work");
assert!(updated_something, "Should have updated a row");
larry.update(&conn).expect("Updating should work");
let larry_copy = Person::get_by_id(&conn, larry_id).expect("Querying a row should work");
assert_eq!(