Re-add savepoint method to Transaction

Revives #184.

The rewrite for async/await and Tokio accidentally lost functionality
that allowed users to assign specific names to savepoints when using
nested transactions. This functionality had originally been added
in #184 and had been updated in #374.

This commit revives this functionality using a similar scheme to the
one that existed before. This should allow CockroachDB users to update
to the next patch release of version `0.17`.
This commit is contained in:
Nathan VanBenschoten
2020-05-01 12:55:48 -04:00
parent e3d3c6d5cd
commit 64d6e97eff
3 changed files with 97 additions and 16 deletions

View File

@@ -151,6 +151,57 @@ fn nested_transactions() {
assert_eq!(rows[2].get::<_, i32>(0), 4);
}
#[test]
fn savepoints() {
let mut client = Client::connect("host=localhost port=5433 user=postgres", NoTls).unwrap();
client
.batch_execute("CREATE TEMPORARY TABLE foo (id INT PRIMARY KEY)")
.unwrap();
let mut transaction = client.transaction().unwrap();
transaction
.execute("INSERT INTO foo (id) VALUES (1)", &[])
.unwrap();
let mut savepoint1 = transaction.savepoint("savepoint1").unwrap();
savepoint1
.execute("INSERT INTO foo (id) VALUES (2)", &[])
.unwrap();
savepoint1.rollback().unwrap();
let rows = transaction
.query("SELECT id FROM foo ORDER BY id", &[])
.unwrap();
assert_eq!(rows.len(), 1);
assert_eq!(rows[0].get::<_, i32>(0), 1);
let mut savepoint2 = transaction.savepoint("savepoint2").unwrap();
savepoint2
.execute("INSERT INTO foo (id) VALUES(3)", &[])
.unwrap();
let mut savepoint3 = savepoint2.savepoint("savepoint3").unwrap();
savepoint3
.execute("INSERT INTO foo (id) VALUES(4)", &[])
.unwrap();
savepoint3.commit().unwrap();
savepoint2.commit().unwrap();
transaction.commit().unwrap();
let rows = client.query("SELECT id FROM foo ORDER BY id", &[]).unwrap();
assert_eq!(rows.len(), 3);
assert_eq!(rows[0].get::<_, i32>(0), 1);
assert_eq!(rows[1].get::<_, i32>(0), 3);
assert_eq!(rows[2].get::<_, i32>(0), 4);
}
#[test]
fn copy_in() {
let mut client = Client::connect("host=localhost port=5433 user=postgres", NoTls).unwrap();

View File

@@ -173,7 +173,7 @@ impl<'a> Transaction<'a> {
CancelToken::new(self.transaction.cancel_token())
}
/// Like `Client::transaction`.
/// Like `Client::transaction`, but creates a nested transaction via a savepoint.
pub fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
let transaction = self.connection.block_on(self.transaction.transaction())?;
Ok(Transaction {
@@ -181,4 +181,15 @@ impl<'a> Transaction<'a> {
transaction,
})
}
/// Like `Client::transaction`, but creates a nested transaction via a savepoint with the specified name.
pub fn savepoint<I>(&mut self, name: I) -> Result<Transaction<'_>, Error>
where
I: Into<String>,
{
let transaction = self.connection.block_on(self.transaction.savepoint(name))?;
Ok(Transaction {
connection: self.connection.as_ref(),
transaction,
})
}
}