Skip to content

Commit 5b80b25

Browse files
committed
Finish up transaction config
1 parent 6f59fb5 commit 5b80b25

File tree

3 files changed

+65
-13
lines changed

3 files changed

+65
-13
lines changed

src/lib.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,11 +1162,18 @@ impl Connection {
11621162
/// trans.commit().unwrap();
11631163
/// ```
11641164
pub fn transaction<'a>(&'a self) -> Result<Transaction<'a>> {
1165+
self.transaction_with(&transaction::Config::new())
1166+
}
1167+
1168+
/// Begins a new transaction with the specified configuration.
1169+
pub fn transaction_with<'a>(&'a self, config: &transaction::Config) -> Result<Transaction<'a>> {
11651170
let mut conn = self.conn.borrow_mut();
11661171
check_desync!(conn);
11671172
assert!(conn.trans_depth == 0,
11681173
"`transaction` must be called on the active transaction");
1169-
try!(conn.quick_query("BEGIN"));
1174+
let mut query = "BEGIN".to_owned();
1175+
config.build_command(&mut query);
1176+
try!(conn.quick_query(&query));
11701177
conn.trans_depth += 1;
11711178
Ok(Transaction::new(self, 1))
11721179
}
@@ -1230,17 +1237,14 @@ impl Connection {
12301237
IsolationLevel::parse(result[0][0].as_ref().unwrap())
12311238
}
12321239

1233-
/// Sets the isolation level which will be used for future transactions.
1234-
///
1235-
/// This is a simple wrapper around `SET TRANSACTION ISOLATION LEVEL ...`.
1236-
///
1237-
/// # Note
1240+
/// # Deprecated
12381241
///
1239-
/// This will not change the behavior of an active transaction.
1242+
/// Use `Connection::set_transaction_config` instead.
12401243
pub fn set_transaction_isolation(&self, level: IsolationLevel) -> Result<()> {
12411244
self.set_transaction_config(transaction::Config::new().isolation_level(level))
12421245
}
12431246

1247+
/// Sets the configuration that will be used for future transactions.
12441248
pub fn set_transaction_config(&self, config: &transaction::Config) -> Result<()> {
12451249
let mut command = "SET SESSION CHARACTERISTICS AS TRANSACTION".to_owned();
12461250
config.build_command(&mut command);

src/transaction.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use stmt::Statement;
88
use rows::Rows;
99
use types::ToSql;
1010

11+
/// Configuration of a transaction.
1112
#[derive(Debug)]
1213
pub struct Config {
1314
isolation_level: Option<IsolationLevel>,
@@ -51,6 +52,7 @@ impl ConfigInternals for Config {
5152
}
5253

5354
impl Config {
55+
/// Creates a new `Config` with no configuration overrides.
5456
pub fn new() -> Config {
5557
Config {
5658
isolation_level: None,
@@ -59,16 +61,27 @@ impl Config {
5961
}
6062
}
6163

64+
/// Sets the isolation level of the configuration.
6265
pub fn isolation_level(&mut self, isolation_level: IsolationLevel) -> &mut Config {
6366
self.isolation_level = Some(isolation_level);
6467
self
6568
}
6669

70+
/// Sets the read-only property of a transaction.
71+
///
72+
/// If enabled, a transaction will be unable to modify any persistent
73+
/// database state.
6774
pub fn read_only(&mut self, read_only: bool) -> &mut Config {
6875
self.read_only = Some(read_only);
6976
self
7077
}
7178

79+
/// Sets the deferrable property of a transaction.
80+
///
81+
/// If enabled in a read only, serializable transaction, the transaction may
82+
/// block when created, after which it will run without the normal overhead
83+
/// of a serializable transaction and will not be forced to roll back due
84+
/// to serialization failures.
7285
pub fn deferrable(&mut self, deferrable: bool) -> &mut Config {
7386
self.deferrable = Some(deferrable);
7487
self
@@ -193,6 +206,13 @@ impl<'conn> Transaction<'conn> {
193206
self.conn.conn.borrow().trans_depth == self.depth
194207
}
195208

209+
/// Alters the configuration of the active transaction.
210+
pub fn set_config(&self, config: &Config) -> Result<()> {
211+
let mut command = "SET TRANSACTION".to_owned();
212+
config.build_command(&mut command);
213+
self.batch_execute(&command)
214+
}
215+
196216
/// Determines if the transaction is currently set to commit or roll back.
197217
pub fn will_commit(&self) -> bool {
198218
self.commit.get()

tests/test.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,8 @@ use std::io;
1313
use std::io::prelude::*;
1414
use std::time::Duration;
1515

16-
use postgres::{HandleNotice,
17-
Connection,
18-
GenericConnection,
19-
SslMode,
20-
IntoConnectParams,
21-
IsolationLevel};
16+
use postgres::{HandleNotice, Connection, GenericConnection, SslMode, IntoConnectParams,
17+
IsolationLevel, transaction};
2218
use postgres::error::{Error, ConnectError, DbError};
2319
use postgres::types::{Oid, Type, Kind, WrongType};
2420
use postgres::error::SqlState::{SyntaxError,
@@ -1020,3 +1016,35 @@ fn test_conn_query() {
10201016
.collect::<Vec<i32>>();
10211017
assert_eq!(ids, [1, 2, 3]);
10221018
}
1019+
1020+
#[test]
1021+
fn transaction_config() {
1022+
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
1023+
let mut config = transaction::Config::new();
1024+
config.isolation_level(IsolationLevel::Serializable)
1025+
.read_only(true)
1026+
.deferrable(true);
1027+
conn.set_transaction_config(&config).unwrap();
1028+
}
1029+
1030+
#[test]
1031+
fn transaction_with() {
1032+
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
1033+
let mut config = transaction::Config::new();
1034+
config.isolation_level(IsolationLevel::Serializable)
1035+
.read_only(true)
1036+
.deferrable(true);
1037+
conn.transaction_with(&config).unwrap().finish().unwrap();
1038+
}
1039+
1040+
#[test]
1041+
fn transaction_set_config() {
1042+
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
1043+
let trans = conn.transaction().unwrap();
1044+
let mut config = transaction::Config::new();
1045+
config.isolation_level(IsolationLevel::Serializable)
1046+
.read_only(true)
1047+
.deferrable(true);
1048+
trans.set_config(&config).unwrap();
1049+
trans.finish().unwrap();
1050+
}

0 commit comments

Comments
 (0)