diff --git a/turbosql-impl/src/insert.rs b/turbosql-impl/src/insert.rs index c2a1cf3..7754cb0 100644 --- a/turbosql-impl/src/insert.rs +++ b/turbosql-impl/src/insert.rs @@ -27,6 +27,17 @@ pub(super) fn insert(table: &Table) -> proc_macro2::TokenStream { }) } + fn insert_mut(&mut self) -> Result { + assert!(self.rowid.is_none()); + ::turbosql::__TURBOSQL_DB.with(|db| { + let db = db.borrow_mut(); + let mut stmt = db.prepare_cached(#sql)?; + let result = stmt.insert(&[#( #columns ),*] as &[&dyn ::turbosql::ToSql])?; + self.rowid = Some(result); + Ok(result) + }) + } + fn insert_batch>(rows: &[T]) -> Result<(), ::turbosql::Error> { for row in rows { row.as_ref().insert()?; diff --git a/turbosql-impl/src/lib.rs b/turbosql-impl/src/lib.rs index eb0faec..b733e07 100644 --- a/turbosql-impl/src/lib.rs +++ b/turbosql-impl/src/lib.rs @@ -674,6 +674,7 @@ pub fn turbosql_derive_macro(input: proc_macro::TokenStream) -> proc_macro::Toke let dummy_impl = quote! { impl ::turbosql::Turbosql for #table_ident { fn insert(&self) -> Result { unimplemented!() } + fn insert_mut(&mut self) -> Result { unimplemented!() } fn insert_batch>(rows: &[T]) -> Result<(), ::turbosql::Error> { unimplemented!() } fn update(&self) -> Result { unimplemented!() } fn update_batch>(rows: &[T]) -> Result<(), ::turbosql::Error> { unimplemented!() } @@ -942,7 +943,7 @@ fn create(table: &Table, minitable: &MiniTable) { if old_toml_str.replace("\r\n", "\n") != new_toml_str { #[cfg(not(feature = "test"))] if std::env::var("CI").is_ok() || std::env::var("TURBOSQL_LOCKED_MODE").is_ok() { - abort_call_site!("Change in `{}` detected with CI or TURBOSQL_LOCKED_MODE environment variable set. Make sure your `migrations.toml` file is up-to-date.", migrations_toml_path_lossy); + abort_call_site!("Change in `{}` detected with CI or TURBOSQL_LOCKED_MODE environment variable set. Make sure your `migrations.toml` file is committed and up-to-date.", migrations_toml_path_lossy); }; fs::write(&migrations_toml_path, new_toml_str) .unwrap_or_else(|e| abort_call_site!("Unable to write {}: {:?}", migrations_toml_path_lossy, e)); diff --git a/turbosql/src/lib_inner.rs b/turbosql/src/lib_inner.rs index b918bd7..e4656c6 100644 --- a/turbosql/src/lib_inner.rs +++ b/turbosql/src/lib_inner.rs @@ -24,9 +24,11 @@ pub type Blob = Vec; /// `#[derive(Turbosql)]` generates impls for this trait. pub trait Turbosql { - /// Inserts this row into the database. `rowid` must be `None`. On success, returns the new `rowid`. + /// Insert this row into the database. `rowid` must be `None`. On success, the new `rowid` is returned. fn insert(&self) -> Result; - /// Inserts all rows in the slice into the database. All `rowid`s must be `None`. On success, returns `Ok(())`. + /// Insert this row into the database, and update the `rowid` of the struct to match the new rowid in the database. `rowid` must be `None` on call. On success, the new `rowid` is returned. + fn insert_mut(&mut self) -> Result; + /// Insert all rows in the slice into the database. All `rowid`s must be `None`. On success, returns `Ok(())`. fn insert_batch>(rows: &[T]) -> Result<(), Error>; /// Updates this existing row in the database, based on `rowid`, which must be `Some`. All fields are overwritten in the database. On success, returns the number of rows updated, which should be 1. fn update(&self) -> Result; diff --git a/turbosql/tests/integration_test.rs b/turbosql/tests/integration_test.rs index ba3d966..1951cff 100644 --- a/turbosql/tests/integration_test.rs +++ b/turbosql/tests/integration_test.rs @@ -74,12 +74,18 @@ fn integration_test() { ..Default::default() }; + let mut row2 = row.clone(); + assert_eq!(row.insert().unwrap(), 1); assert_eq!(row.insert().unwrap(), 2); row.rowid = Some(1); row.field_u8 = Some(84); assert_eq!(row.update().unwrap(), 1); + row2.insert_mut().unwrap(); + assert_eq!(row2.rowid, Some(3)); + execute!("DELETE FROM personintegrationtest WHERE rowid=3").unwrap(); + assert_eq!(select!(i64 "1").unwrap(), 1); // assert_eq!(select!(Vec "1").unwrap(), vec![1]); // assert_eq!(select!(Option "1").unwrap(), Some(1));