Compare commits

..

No commits in common. "84efaaad3f46db12345a920872b67a8f7170b526" and "7162c3c891e09fad0e16f42d27a06e64e966e763" have entirely different histories.

4 changed files with 15 additions and 18 deletions

2
Cargo.lock generated
View File

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

View File

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

View File

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

View File

@ -67,7 +67,8 @@ fn test_table_derive_macro() {
.expect("After (mutable) insertion, id should not be None"); .expect("After (mutable) insertion, id should not be None");
larry.age += 1; larry.age += 1;
larry.update(&conn).expect("Updating should work"); let updated_something = larry.update(&conn).expect("Updating should work");
assert!(updated_something, "Should have updated a row");
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!( assert_eq!(