Finish up transaction config
This commit is contained in:
parent
6f59fb5b35
commit
5b80b251a6
18
src/lib.rs
18
src/lib.rs
@ -1162,11 +1162,18 @@ impl Connection {
|
||||
/// trans.commit().unwrap();
|
||||
/// ```
|
||||
pub fn transaction<'a>(&'a self) -> Result<Transaction<'a>> {
|
||||
self.transaction_with(&transaction::Config::new())
|
||||
}
|
||||
|
||||
/// Begins a new transaction with the specified configuration.
|
||||
pub fn transaction_with<'a>(&'a self, config: &transaction::Config) -> Result<Transaction<'a>> {
|
||||
let mut conn = self.conn.borrow_mut();
|
||||
check_desync!(conn);
|
||||
assert!(conn.trans_depth == 0,
|
||||
"`transaction` must be called on the active transaction");
|
||||
try!(conn.quick_query("BEGIN"));
|
||||
let mut query = "BEGIN".to_owned();
|
||||
config.build_command(&mut query);
|
||||
try!(conn.quick_query(&query));
|
||||
conn.trans_depth += 1;
|
||||
Ok(Transaction::new(self, 1))
|
||||
}
|
||||
@ -1230,17 +1237,14 @@ impl Connection {
|
||||
IsolationLevel::parse(result[0][0].as_ref().unwrap())
|
||||
}
|
||||
|
||||
/// Sets the isolation level which will be used for future transactions.
|
||||
/// # Deprecated
|
||||
///
|
||||
/// This is a simple wrapper around `SET TRANSACTION ISOLATION LEVEL ...`.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This will not change the behavior of an active transaction.
|
||||
/// Use `Connection::set_transaction_config` instead.
|
||||
pub fn set_transaction_isolation(&self, level: IsolationLevel) -> Result<()> {
|
||||
self.set_transaction_config(transaction::Config::new().isolation_level(level))
|
||||
}
|
||||
|
||||
/// Sets the configuration that will be used for future transactions.
|
||||
pub fn set_transaction_config(&self, config: &transaction::Config) -> Result<()> {
|
||||
let mut command = "SET SESSION CHARACTERISTICS AS TRANSACTION".to_owned();
|
||||
config.build_command(&mut command);
|
||||
|
@ -8,6 +8,7 @@ use stmt::Statement;
|
||||
use rows::Rows;
|
||||
use types::ToSql;
|
||||
|
||||
/// Configuration of a transaction.
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
isolation_level: Option<IsolationLevel>,
|
||||
@ -51,6 +52,7 @@ impl ConfigInternals for Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Creates a new `Config` with no configuration overrides.
|
||||
pub fn new() -> Config {
|
||||
Config {
|
||||
isolation_level: None,
|
||||
@ -59,16 +61,27 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the isolation level of the configuration.
|
||||
pub fn isolation_level(&mut self, isolation_level: IsolationLevel) -> &mut Config {
|
||||
self.isolation_level = Some(isolation_level);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the read-only property of a transaction.
|
||||
///
|
||||
/// If enabled, a transaction will be unable to modify any persistent
|
||||
/// database state.
|
||||
pub fn read_only(&mut self, read_only: bool) -> &mut Config {
|
||||
self.read_only = Some(read_only);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the deferrable property of a transaction.
|
||||
///
|
||||
/// If enabled in a read only, serializable transaction, the transaction may
|
||||
/// block when created, after which it will run without the normal overhead
|
||||
/// of a serializable transaction and will not be forced to roll back due
|
||||
/// to serialization failures.
|
||||
pub fn deferrable(&mut self, deferrable: bool) -> &mut Config {
|
||||
self.deferrable = Some(deferrable);
|
||||
self
|
||||
@ -193,6 +206,13 @@ impl<'conn> Transaction<'conn> {
|
||||
self.conn.conn.borrow().trans_depth == self.depth
|
||||
}
|
||||
|
||||
/// Alters the configuration of the active transaction.
|
||||
pub fn set_config(&self, config: &Config) -> Result<()> {
|
||||
let mut command = "SET TRANSACTION".to_owned();
|
||||
config.build_command(&mut command);
|
||||
self.batch_execute(&command)
|
||||
}
|
||||
|
||||
/// Determines if the transaction is currently set to commit or roll back.
|
||||
pub fn will_commit(&self) -> bool {
|
||||
self.commit.get()
|
||||
|
@ -13,12 +13,8 @@ use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::time::Duration;
|
||||
|
||||
use postgres::{HandleNotice,
|
||||
Connection,
|
||||
GenericConnection,
|
||||
SslMode,
|
||||
IntoConnectParams,
|
||||
IsolationLevel};
|
||||
use postgres::{HandleNotice, Connection, GenericConnection, SslMode, IntoConnectParams,
|
||||
IsolationLevel, transaction};
|
||||
use postgres::error::{Error, ConnectError, DbError};
|
||||
use postgres::types::{Oid, Type, Kind, WrongType};
|
||||
use postgres::error::SqlState::{SyntaxError,
|
||||
@ -1020,3 +1016,35 @@ fn test_conn_query() {
|
||||
.collect::<Vec<i32>>();
|
||||
assert_eq!(ids, [1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_config() {
|
||||
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
|
||||
let mut config = transaction::Config::new();
|
||||
config.isolation_level(IsolationLevel::Serializable)
|
||||
.read_only(true)
|
||||
.deferrable(true);
|
||||
conn.set_transaction_config(&config).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_with() {
|
||||
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
|
||||
let mut config = transaction::Config::new();
|
||||
config.isolation_level(IsolationLevel::Serializable)
|
||||
.read_only(true)
|
||||
.deferrable(true);
|
||||
conn.transaction_with(&config).unwrap().finish().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_set_config() {
|
||||
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
|
||||
let trans = conn.transaction().unwrap();
|
||||
let mut config = transaction::Config::new();
|
||||
config.isolation_level(IsolationLevel::Serializable)
|
||||
.read_only(true)
|
||||
.deferrable(true);
|
||||
trans.set_config(&config).unwrap();
|
||||
trans.finish().unwrap();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user