Skip to content

Commit

Permalink
feat(postgres): use flat command-list instead of hashmap
Browse files Browse the repository at this point in the history
  • Loading branch information
liushuyu committed Nov 25, 2021
1 parent a11bea1 commit 0d98865
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 48 deletions.
4 changes: 2 additions & 2 deletions sqlx-core/src/postgres/connection/establish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ impl PgConnection {
params.push(("application_name", application_name));
}

for (k, v) in options.options.iter() {
params.push((k, v));
if let Some(ref options) = options.options {
params.push(("options", options));
}

stream
Expand Down
1 change: 0 additions & 1 deletion sqlx-core/src/postgres/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ pub use error::{PgDatabaseError, PgErrorPosition};
pub use listener::{PgListener, PgNotification};
pub use message::PgSeverity;
pub use options::{PgConnectOptions, PgSslMode};
pub(crate) use options::parse_options;
pub use query_result::PgQueryResult;
pub use row::PgRow;
pub use statement::PgStatement;
Expand Down
36 changes: 11 additions & 25 deletions sqlx-core/src/postgres/options/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::env::var;
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -87,7 +86,7 @@ pub struct PgConnectOptions {
pub(crate) statement_cache_capacity: usize,
pub(crate) application_name: Option<String>,
pub(crate) log_settings: LogSettings,
pub(crate) options: HashMap<String, String>,
pub(crate) options: Option<String>,
}

impl Default for PgConnectOptions {
Expand Down Expand Up @@ -148,9 +147,7 @@ impl PgConnectOptions {
statement_cache_capacity: 100,
application_name: var("PGAPPNAME").ok(),
log_settings: Default::default(),
options: var("PGOPTIONS")
.and_then(|v| Ok(parse_options(&v).unwrap_or_default().into_iter().collect()))
.unwrap_or_default(),
options: var("PGOPTIONS").ok(),
}
}

Expand Down Expand Up @@ -332,16 +329,23 @@ impl PgConnectOptions {
/// ```rust
/// # use sqlx_core::postgres::PgConnectOptions;
/// let options = PgConnectOptions::new()
/// .options(&[("geqo", "off"), ("statement_timeout", "5min")]);
/// .options([("geqo", "off"), ("statement_timeout", "5min")]);
/// ```
pub fn options<K, V, I>(mut self, options: I) -> Self
where
K: ToString,
V: ToString,
I: IntoIterator<Item = (K, V)>,
{
let mut options_str = String::new();
for (k, v) in options {
self.options.insert(k.to_string(), v.to_string());
options_str += &format!("-c {}={}", k.to_string(), v.to_string());
}
if let Some(ref mut v) = self.options {
v.push(' ');
v.push_str(&options_str);
} else {
self.options = Some(options_str);
}
self
}
Expand All @@ -363,24 +367,6 @@ impl PgConnectOptions {
}
}

/// Parse a libpq style options string
pub(crate) fn parse_options(input: &str) -> Option<Vec<(String, String)>> {
let mut options = Vec::new();
for part in input.split(' ') {
let part = part.trim();
if part.is_empty() || part == "-c" {
continue;
}
let pair = part.splitn(2, '=').collect::<Vec<_>>();
if pair.len() != 2 {
return None;
}
options.push((pair[0].to_string(), pair[1].to_string()));
}

Some(options)
}

fn default_host(port: u16) -> String {
// try to check for the existence of a unix socket and uses that
let socket = format!(".s.PGSQL.{}", port);
Expand Down
29 changes: 9 additions & 20 deletions sqlx-core/src/postgres/options/parse.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::Error;
use crate::postgres::{parse_options, PgConnectOptions};
use crate::postgres::PgConnectOptions;
use percent_encoding::percent_decode_str;
use std::net::IpAddr;
use std::str::FromStr;
Expand Down Expand Up @@ -86,8 +86,11 @@ impl FromStr for PgConnectOptions {
"application_name" => options = options.application_name(&*value),

"options" => {
if let Some(value) = parse_options(&value) {
options = options.options(value);
if let Some(options) = options.options.as_mut() {
options.push(' ');
options.push_str(&*value);
} else {
options.options = Some(value.to_string());
}
}

Expand Down Expand Up @@ -209,29 +212,15 @@ fn it_parses_socket_correctly_with_username_percent_encoded() {
}
#[test]
fn it_parses_libpq_options_correctly() {
let uri = "postgres:///?options=-c%20synchronous_commit%3Doff%20-c%20search_path%3Dpostgres";
let uri = "postgres:///?options=-c%20synchronous_commit%3Doff%20--search_path%3Dpostgres";
let opts = PgConnectOptions::from_str(uri).unwrap();

assert_eq!(
Some(&"off".to_string()),
opts.options.get("synchronous_commit")
);
assert_eq!(
Some(&"postgres".to_string()),
opts.options.get("search_path")
);
assert_eq!(Some("-c synchronous_commit=off --search_path=postgres".into()), opts.options);
}
#[test]
fn it_parses_sqlx_options_correctly() {
let uri = "postgres:///?options[synchronous_commit]=off&options[search_path]=postgres";
let opts = PgConnectOptions::from_str(uri).unwrap();

assert_eq!(
Some(&"off".to_string()),
opts.options.get("synchronous_commit")
);
assert_eq!(
Some(&"postgres".to_string()),
opts.options.get("search_path")
);
assert_eq!(Some("-c synchronous_commit=off -c search_path=postgres".into()), opts.options);
}

0 comments on commit 0d98865

Please sign in to comment.