Skip to content

Commit 5b353aa

Browse files
committed
Add a SessionInfo field to ToSql and FromSql methods
Backend parameters such as timezone or server_version can be useful for conversion methods to have access to.
1 parent dac19e8 commit 5b353aa

File tree

8 files changed

+120
-69
lines changed

8 files changed

+120
-69
lines changed

src/lib.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ use std::path::PathBuf;
7878

7979
pub use error::{Error, ConnectError, SqlState, DbError, ErrorPosition};
8080
#[doc(inline)]
81-
pub use types::{Oid, Type, Kind, ToSql, FromSql};
81+
pub use types::{Oid, Type, Kind, ToSql, FromSql, SessionInfo};
8282
use io::{StreamWrapper, NegotiateSsl};
8383
use types::IsNull;
8484
#[doc(inline)]
@@ -474,6 +474,10 @@ struct CachedStatement {
474474
columns: Vec<Column>,
475475
}
476476

477+
trait SessionInfoNew<'a> {
478+
fn new(conn: &'a InnerConnection) -> SessionInfo<'a>;
479+
}
480+
477481
struct InnerConnection {
478482
stream: BufStream<Box<StreamWrapper>>,
479483
notice_handler: Box<HandleNotice>,
@@ -826,7 +830,7 @@ impl InnerConnection {
826830

827831
// Ew @ doing this manually :(
828832
let mut buf = vec![];
829-
let value = match try!(oid.to_sql_checked(&Type::Oid, &mut buf)) {
833+
let value = match try!(oid.to_sql_checked(&Type::Oid, &mut buf, &SessionInfo::new(self))) {
830834
IsNull::Yes => None,
831835
IsNull::No => Some(buf),
832836
};
@@ -854,12 +858,16 @@ impl InnerConnection {
854858
let (name, elem_oid, rngsubtype): (String, Oid, Option<Oid>) =
855859
match try!(self.read_message()) {
856860
DataRow { row } => {
861+
let ctx = SessionInfo::new(self);
857862
(try!(FromSql::from_sql_nullable(&Type::Name,
858-
row[0].as_ref().map(|r| &**r).as_mut())),
863+
row[0].as_ref().map(|r| &**r).as_mut(),
864+
&ctx)),
859865
try!(FromSql::from_sql_nullable(&Type::Oid,
860-
row[1].as_ref().map(|r| &**r).as_mut())),
866+
row[1].as_ref().map(|r| &**r).as_mut(),
867+
&ctx)),
861868
try!(FromSql::from_sql_nullable(&Type::Oid,
862-
row[2].as_ref().map(|r| &**r).as_mut())))
869+
row[2].as_ref().map(|r| &**r).as_mut(),
870+
&ctx)))
863871
}
864872
ErrorResponse { fields } => {
865873
try!(self.wait_for_ready());
@@ -1221,7 +1229,8 @@ impl Connection {
12211229
self.conn.borrow().cancel_data
12221230
}
12231231

1224-
/// Returns the value of the specified parameter.
1232+
/// Returns the value of the specified Postgres backend parameter, such as
1233+
/// `timezone` or `server_version`.
12251234
pub fn parameter(&self, param: &str) -> Option<String> {
12261235
self.conn.borrow().parameters.get(param).cloned()
12271236
}
@@ -1433,7 +1442,7 @@ impl<'conn> Statement<'conn> {
14331442
let mut values = vec![];
14341443
for (param, ty) in params.iter().zip(self.param_types.iter()) {
14351444
let mut buf = vec![];
1436-
match try!(param.to_sql_checked(ty, &mut buf)) {
1445+
match try!(param.to_sql_checked(ty, &mut buf, &SessionInfo::new(&*conn))) {
14371446
IsNull::Yes => values.push(None),
14381447
IsNull::No => values.push(Some(buf)),
14391448
}
@@ -1854,7 +1863,9 @@ impl<'a> Row<'a> {
18541863
if !<T as FromSql>::accepts(ty) {
18551864
return Err(Error::WrongType(ty.clone()));
18561865
}
1857-
FromSql::from_sql_nullable(ty, self.data[idx].as_ref().map(|e| &**e).as_mut())
1866+
let conn = self.stmt.conn.conn.borrow();
1867+
FromSql::from_sql_nullable(ty, self.data[idx].as_ref().map(|e| &**e).as_mut(),
1868+
&SessionInfo::new(&*conn))
18581869
}
18591870

18601871
/// Retrieves the contents of a field of the row.
@@ -2151,7 +2162,7 @@ impl<'a> CopyInStatement<'a> {
21512162
match (row.next(), types.next()) {
21522163
(Some(val), Some(ty)) => {
21532164
let mut inner_buf = vec![];
2154-
match val.to_sql_checked(ty, &mut inner_buf) {
2165+
match val.to_sql_checked(ty, &mut inner_buf, &SessionInfo::new(&*conn)) {
21552166
Ok(IsNull::Yes) => {
21562167
let _ = buf.write_i32::<BigEndian>(-1);
21572168
}

src/types/chrono.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
55
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC};
66

77
use Result;
8-
use types::{FromSql, ToSql, IsNull, Type};
8+
use types::{FromSql, ToSql, IsNull, Type, SessionInfo};
99

1010
fn base() -> NaiveDateTime {
1111
NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0)
1212
}
1313

1414
impl FromSql for NaiveDateTime {
15-
fn from_sql<R: Read>(_: &Type, raw: &mut R) -> Result<NaiveDateTime> {
15+
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDateTime> {
1616
let t = try!(raw.read_i64::<BigEndian>());
1717
Ok(base() + Duration::microseconds(t))
1818
}
@@ -21,7 +21,7 @@ impl FromSql for NaiveDateTime {
2121
}
2222

2323
impl ToSql for NaiveDateTime {
24-
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W) -> Result<IsNull> {
24+
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
2525
let t = (*self - base()).num_microseconds().unwrap();
2626
try!(w.write_i64::<BigEndian>(t));
2727
Ok(IsNull::No)
@@ -32,7 +32,7 @@ impl ToSql for NaiveDateTime {
3232
}
3333

3434
impl FromSql for DateTime<UTC> {
35-
fn from_sql<R: Read>(type_: &Type, raw: &mut R) -> Result<DateTime<UTC>> {
35+
fn from_sql<R: Read>(type_: &Type, raw: &mut R, _: &SessionInfo) -> Result<DateTime<UTC>> {
3636
let naive = try!(NaiveDateTime::from_sql(type_, raw));
3737
Ok(DateTime::from_utc(naive, UTC))
3838
}
@@ -41,7 +41,8 @@ impl FromSql for DateTime<UTC> {
4141
}
4242

4343
impl ToSql for DateTime<UTC> {
44-
fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W) -> Result<IsNull> {
44+
fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, _: &SessionInfo)
45+
-> Result<IsNull> {
4546
self.naive_utc().to_sql(type_, w)
4647
}
4748

@@ -50,7 +51,7 @@ impl ToSql for DateTime<UTC> {
5051
}
5152

5253
impl FromSql for NaiveDate {
53-
fn from_sql<R: Read>(_: &Type, raw: &mut R) -> Result<NaiveDate> {
54+
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDate> {
5455
let jd = try!(raw.read_i32::<BigEndian>());
5556
Ok(base().date() + Duration::days(jd as i64))
5657
}
@@ -59,7 +60,7 @@ impl FromSql for NaiveDate {
5960
}
6061

6162
impl ToSql for NaiveDate {
62-
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W) -> Result<IsNull> {
63+
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
6364
let jd = *self - base().date();
6465
try!(w.write_i32::<BigEndian>(jd.num_days() as i32));
6566
Ok(IsNull::No)
@@ -70,7 +71,7 @@ impl ToSql for NaiveDate {
7071
}
7172

7273
impl FromSql for NaiveTime {
73-
fn from_sql<R: Read>(_: &Type, raw: &mut R) -> Result<NaiveTime> {
74+
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveTime> {
7475
let usec = try!(raw.read_i64::<BigEndian>());
7576
Ok(NaiveTime::from_hms(0, 0, 0) + Duration::microseconds(usec))
7677
}
@@ -79,7 +80,7 @@ impl FromSql for NaiveTime {
7980
}
8081

8182
impl ToSql for NaiveTime {
82-
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W) -> Result<IsNull> {
83+
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result<IsNull> {
8384
let delta = *self - NaiveTime::from_hms(0, 0, 0);
8485
try!(w.write_i64::<BigEndian>(delta.num_microseconds().unwrap()));
8586
Ok(IsNull::No)

0 commit comments

Comments
 (0)