Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion powersync/src/db/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ impl<'a> TransactionGuard<'a> {
}

pub fn commit(mut self) -> Result<(), PowerSyncError> {
self.inner.exec(c"COMMIT")?;
self.active = false;
self.inner.exec(c"COMMIT")
Ok(())
}

fn rollback_internal(&mut self) -> Result<(), PowerSyncError> {
Expand Down Expand Up @@ -213,3 +214,42 @@ fn path_to_cstring(p: &Path) -> Result<CString, PowerSyncError> {
})?,
)
}

#[cfg(test)]
mod tests {
use super::*;
use powersync_sqlite_nostd::bindings::{SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE};

#[test]
fn failed_commit_rolls_back_before_reusing_connection() {
let mut connection = SqliteConnection::from(
RawSqliteConnection::open(c":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
.unwrap(),
);
connection
.exec(
c"PRAGMA foreign_keys = ON;
CREATE TABLE parents (id INTEGER PRIMARY KEY);
CREATE TABLE children (parent_id INTEGER REFERENCES parents(id)
DEFERRABLE INITIALLY DEFERRED);",
)
.unwrap();

let tx = TransactionGuard::new(&mut connection).unwrap();
tx.inner.exec(c"INSERT INTO children VALUES (1)").unwrap();
assert!(tx.commit().is_err());

let tx = TransactionGuard::new(&mut connection).unwrap();
let count = tx.inner.prepare("SELECT count(*) FROM children").unwrap();
assert_eq!(count.step().unwrap(), ResultCode::ROW);
assert_eq!(count.column_int64(0), 0);
drop(count);
tx.inner
.exec(
c"INSERT INTO parents VALUES (1);
INSERT INTO children VALUES (1)",
)
.unwrap();
tx.commit().unwrap();
}
}
Loading