Skip to content

Commit d6c2835

Browse files
authored
Merge pull request #1110 from chandr-andr/feature/add_read_only_session_attr
Add `ReadOnly` in `TargetSessionAttrs`
2 parents ba1b4cf + 6a01730 commit d6c2835

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

tokio-postgres/src/config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ pub enum TargetSessionAttrs {
3434
Any,
3535
/// The session must allow writes.
3636
ReadWrite,
37+
/// The session allow only reads.
38+
ReadOnly,
3739
}
3840

3941
/// TLS configuration.
@@ -622,6 +624,7 @@ impl Config {
622624
let target_session_attrs = match value {
623625
"any" => TargetSessionAttrs::Any,
624626
"read-write" => TargetSessionAttrs::ReadWrite,
627+
"read-only" => TargetSessionAttrs::ReadOnly,
625628
_ => {
626629
return Err(Error::config_parse(Box::new(InvalidValue(
627630
"target_session_attrs",

tokio-postgres/src/connect.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ where
160160
let has_hostname = hostname.is_some();
161161
let (mut client, mut connection) = connect_raw(socket, tls, has_hostname, config).await?;
162162

163-
if let TargetSessionAttrs::ReadWrite = config.target_session_attrs {
163+
if config.target_session_attrs != TargetSessionAttrs::Any {
164164
let rows = client.simple_query_raw("SHOW transaction_read_only");
165165
pin_mut!(rows);
166166

@@ -185,11 +185,21 @@ where
185185

186186
match next.await.transpose()? {
187187
Some(SimpleQueryMessage::Row(row)) => {
188-
if row.try_get(0)? == Some("on") {
188+
let read_only_result = row.try_get(0)?;
189+
if read_only_result == Some("on")
190+
&& config.target_session_attrs == TargetSessionAttrs::ReadWrite
191+
{
189192
return Err(Error::connect(io::Error::new(
190193
io::ErrorKind::PermissionDenied,
191194
"database does not allow writes",
192195
)));
196+
} else if read_only_result == Some("off")
197+
&& config.target_session_attrs == TargetSessionAttrs::ReadOnly
198+
{
199+
return Err(Error::connect(io::Error::new(
200+
io::ErrorKind::PermissionDenied,
201+
"database is not read only",
202+
)));
193203
} else {
194204
break;
195205
}

tokio-postgres/tests/test/parse.rs

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ fn settings() {
3434
.keepalives_idle(Duration::from_secs(30))
3535
.target_session_attrs(TargetSessionAttrs::ReadWrite),
3636
);
37+
check(
38+
"connect_timeout=3 keepalives=0 keepalives_idle=30 target_session_attrs=read-only",
39+
Config::new()
40+
.connect_timeout(Duration::from_secs(3))
41+
.keepalives(false)
42+
.keepalives_idle(Duration::from_secs(30))
43+
.target_session_attrs(TargetSessionAttrs::ReadOnly),
44+
);
3745
}
3846

3947
#[test]

0 commit comments

Comments
 (0)