diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-10-05 01:21:16 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-10-05 01:21:16 -0400 |
| commit | 19b53b1ace4be040a7420080c31e8c95ca9eeb8c (patch) | |
| tree | adee41f47184f6ebaf4a9d15c3fca8c6389da8ff | |
| parent | 2f621416f69e522f412e34ebbf29e655541414bd (diff) | |
Implement `sqlite3_backup_step`'s multi-step protocol.
| -rw-r--r-- | src/db/backup.rs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/db/backup.rs b/src/db/backup.rs index 212fa4e..b09bb3d 100644 --- a/src/db/backup.rs +++ b/src/db/backup.rs @@ -6,8 +6,7 @@ use std::{ use libsqlite3_sys::{ sqlite3, sqlite3_backup, sqlite3_backup_finish, sqlite3_backup_init, sqlite3_backup_step, - sqlite3_errmsg, sqlite3_errstr, sqlite3_extended_errcode, SQLITE_BUSY, SQLITE_LOCKED, - SQLITE_OK, + sqlite3_errmsg, sqlite3_errstr, sqlite3_extended_errcode, SQLITE_DONE, SQLITE_OK, }; use sqlx::sqlite::SqlitePool; @@ -43,7 +42,14 @@ impl<'p> Backup<'p> { let mut from = from.lock_handle().await?; let handle = Self::start(to.as_raw_handle(), from.as_raw_handle())?; - let step_result = Self::step(handle, -1); + let step_result = loop { + match Self::step(handle, -1) { + Err(error) => break Err(error), + Ok(SQLITE_DONE) => break Ok(()), + Ok(SQLITE_OK) => (), // keep pumping the backup step function + Ok(other) => panic!("unexpected step result: {other}"), + } + }; Self::finish(handle)?; step_result @@ -72,12 +78,12 @@ impl<'p> Backup<'p> { Ok(NonNull::new(handle).expect("backup handle is non-null")) } - fn step(handle: NonNull<sqlite3_backup>, pages: c_int) -> Result<(), Error> { + fn step(handle: NonNull<sqlite3_backup>, pages: c_int) -> Result<c_int, Error> { let step = unsafe { sqlite3_backup_step(handle.as_ptr(), pages) }; - if [SQLITE_BUSY, SQLITE_LOCKED].contains(&step) { - Err(Error::from_code(step)) + if [SQLITE_DONE, SQLITE_OK].contains(&step) { + Ok(step) } else { - Ok(()) + Err(Error::from_code(step)) } } |
