Skip to content

Commit a4f0c3b

Browse files
committed
Don't clone cached statement info
1 parent 54735d9 commit a4f0c3b

File tree

2 files changed

+46
-48
lines changed

2 files changed

+46
-48
lines changed

src/lib.rs

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ use std::io::prelude::*;
6565
use std::marker::Sync as StdSync;
6666
use std::mem;
6767
use std::result;
68+
use std::sync::Arc;
6869
use std::time::Duration;
6970
#[cfg(feature = "unix_socket")]
7071
use std::path::PathBuf;
@@ -361,8 +362,7 @@ pub enum SslMode<'a> {
361362
Require(&'a NegotiateSsl),
362363
}
363364

364-
#[derive(Clone)]
365-
struct CachedStatement {
365+
struct StatementInfo {
366366
name: String,
367367
param_types: Vec<Type>,
368368
columns: Vec<Column>,
@@ -374,7 +374,7 @@ struct InnerConnection {
374374
notifications: VecDeque<Notification>,
375375
cancel_data: CancelData,
376376
unknown_types: HashMap<Oid, Other>,
377-
cached_statements: HashMap<String, CachedStatement>,
377+
cached_statements: HashMap<String, Arc<StatementInfo>>,
378378
parameters: HashMap<String, String>,
379379
next_stmt_id: u32,
380380
trans_depth: u32,
@@ -670,28 +670,33 @@ impl InnerConnection {
670670
fn prepare<'a>(&mut self, query: &str, conn: &'a Connection) -> Result<Statement<'a>> {
671671
let stmt_name = self.make_stmt_name();
672672
let (param_types, columns) = try!(self.raw_prepare(&stmt_name, query));
673-
Ok(Statement::new(conn, stmt_name, param_types, columns, Cell::new(0), false))
673+
let info = Arc::new(StatementInfo {
674+
name: stmt_name,
675+
param_types: param_types,
676+
columns: columns,
677+
});
678+
Ok(Statement::new(conn, info, Cell::new(0), false))
674679
}
675680

676681
fn prepare_cached<'a>(&mut self, query: &str, conn: &'a Connection) -> Result<Statement<'a>> {
677-
let stmt = self.cached_statements.get(query).cloned();
682+
let info = self.cached_statements.get(query).cloned();
678683

679-
let CachedStatement { name, param_types, columns } = match stmt {
680-
Some(stmt) => stmt,
684+
let info = match info {
685+
Some(info) => info,
681686
None => {
682687
let stmt_name = self.make_stmt_name();
683688
let (param_types, columns) = try!(self.raw_prepare(&stmt_name, query));
684-
let stmt = CachedStatement {
689+
let info = Arc::new(StatementInfo {
685690
name: stmt_name,
686691
param_types: param_types,
687692
columns: columns,
688-
};
689-
self.cached_statements.insert(query.to_owned(), stmt.clone());
690-
stmt
693+
});
694+
self.cached_statements.insert(query.to_owned(), info.clone());
695+
info
691696
}
692697
};
693698

694-
Ok(Statement::new(conn, name, param_types, columns, Cell::new(0), true))
699+
Ok(Statement::new(conn, info, Cell::new(0), true))
695700
}
696701

697702
fn close_statement(&mut self, name: &str, type_: u8) -> Result<()> {
@@ -959,12 +964,12 @@ impl Connection {
959964
/// ```
960965
pub fn execute(&self, query: &str, params: &[&ToSql]) -> Result<u64> {
961966
let (param_types, columns) = try!(self.conn.borrow_mut().raw_prepare("", query));
962-
let stmt = Statement::new(self,
963-
"".to_owned(),
964-
param_types,
965-
columns,
966-
Cell::new(0),
967-
true);
967+
let info = Arc::new(StatementInfo {
968+
name: String::new(),
969+
param_types: param_types,
970+
columns: columns,
971+
});
972+
let stmt = Statement::new(self, info, Cell::new(0), true);
968973
stmt.execute(params)
969974
}
970975

@@ -995,12 +1000,12 @@ impl Connection {
9951000
/// ```
9961001
pub fn query<'a>(&'a self, query: &str, params: &[&ToSql]) -> Result<Rows<'a>> {
9971002
let (param_types, columns) = try!(self.conn.borrow_mut().raw_prepare("", query));
998-
let stmt = Statement::new(self,
999-
"".to_owned(),
1000-
param_types,
1001-
columns,
1002-
Cell::new(0),
1003-
true);
1003+
let info = Arc::new(StatementInfo {
1004+
name: String::new(),
1005+
param_types: param_types,
1006+
columns: columns,
1007+
});
1008+
let stmt = Statement::new(self, info, Cell::new(0), true);
10041009
stmt.into_query(params)
10051010
}
10061011

@@ -1497,9 +1502,7 @@ trait SessionInfoNew<'a> {
14971502

14981503
trait StatementInternals<'conn> {
14991504
fn new(conn: &'conn Connection,
1500-
name: String,
1501-
param_types: Vec<Type>,
1502-
columns: Vec<Column>,
1505+
info: Arc<StatementInfo>,
15031506
next_portal_id: Cell<u32>,
15041507
finished: bool)
15051508
-> Statement<'conn>;

src/stmt.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::cell::{Cell, RefMut};
44
use std::collections::VecDeque;
55
use std::fmt;
66
use std::io::{self, Read, Write};
7+
use std::sync::Arc;
78

89
use error::{Error, DbError};
910
use types::{SessionInfo, Type, ToSql, IsNull};
@@ -13,24 +14,22 @@ use message::WriteMessage;
1314
use util;
1415
use rows::{Rows, LazyRows};
1516
use {read_rows, bad_response, Connection, Transaction, StatementInternals, Result, RowsNew};
16-
use {InnerConnection, SessionInfoNew, LazyRowsNew, DbErrorNew, ColumnNew};
17+
use {InnerConnection, SessionInfoNew, LazyRowsNew, DbErrorNew, ColumnNew, StatementInfo};
1718

1819
/// A prepared statement.
1920
pub struct Statement<'conn> {
2021
conn: &'conn Connection,
21-
name: String,
22-
param_types: Vec<Type>,
23-
columns: Vec<Column>,
22+
info: Arc<StatementInfo>,
2423
next_portal_id: Cell<u32>,
2524
finished: bool,
2625
}
2726

2827
impl<'a> fmt::Debug for Statement<'a> {
2928
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
3029
fmt.debug_struct("Statement")
31-
.field("name", &self.name)
32-
.field("parameter_types", &self.param_types)
33-
.field("columns", &self.columns)
30+
.field("name", &self.info.name)
31+
.field("parameter_types", &self.info.param_types)
32+
.field("columns", &self.info.columns)
3433
.finish()
3534
}
3635
}
@@ -43,17 +42,13 @@ impl<'conn> Drop for Statement<'conn> {
4342

4443
impl<'conn> StatementInternals<'conn> for Statement<'conn> {
4544
fn new(conn: &'conn Connection,
46-
name: String,
47-
param_types: Vec<Type>,
48-
columns: Vec<Column>,
45+
info: Arc<StatementInfo>,
4946
next_portal_id: Cell<u32>,
5047
finished: bool)
5148
-> Statement<'conn> {
5249
Statement {
5350
conn: conn,
54-
name: name,
55-
param_types: param_types,
56-
columns: columns,
51+
info: info,
5752
next_portal_id: next_portal_id,
5853
finished: finished,
5954
}
@@ -76,7 +71,7 @@ impl<'conn> Statement<'conn> {
7671
self.finished = true;
7772
let mut conn = self.conn.conn.borrow_mut();
7873
check_desync!(conn);
79-
conn.close_statement(&self.name, b'S')
74+
conn.close_statement(&self.info.name, b'S')
8075
} else {
8176
Ok(())
8277
}
@@ -86,13 +81,13 @@ impl<'conn> Statement<'conn> {
8681
let mut conn = self.conn.conn.borrow_mut();
8782
assert!(self.param_types().len() == params.len(),
8883
"expected {} parameters but got {}",
89-
self.param_types.len(),
84+
self.param_types().len(),
9085
params.len());
9186
debug!("executing statement {} with parameters: {:?}",
92-
self.name,
87+
self.info.name,
9388
params);
9489
let mut values = vec![];
95-
for (param, ty) in params.iter().zip(self.param_types.iter()) {
90+
for (param, ty) in params.iter().zip(self.param_types()) {
9691
let mut buf = vec![];
9792
match try!(param.to_sql_checked(ty, &mut buf, &SessionInfo::new(&*conn))) {
9893
IsNull::Yes => values.push(None),
@@ -102,7 +97,7 @@ impl<'conn> Statement<'conn> {
10297

10398
try!(conn.write_messages(&[Bind {
10499
portal: portal_name,
105-
statement: &self.name,
100+
statement: &self.info.name,
106101
formats: &[1],
107102
values: &values,
108103
result_formats: &[1],
@@ -140,12 +135,12 @@ impl<'conn> Statement<'conn> {
140135

141136
/// Returns a slice containing the expected parameter types.
142137
pub fn param_types(&self) -> &[Type] {
143-
&self.param_types
138+
&self.info.param_types
144139
}
145140

146141
/// Returns a slice describing the columns of the result of the query.
147142
pub fn columns(&self) -> &[Column] {
148-
&self.columns
143+
&self.info.columns
149144
}
150145

151146
/// Executes the prepared statement, returning the number of rows modified.
@@ -279,7 +274,7 @@ impl<'conn> Statement<'conn> {
279274

280275
let id = self.next_portal_id.get();
281276
self.next_portal_id.set(id + 1);
282-
let portal_name = format!("{}p{}", self.name, id);
277+
let portal_name = format!("{}p{}", self.info.name, id);
283278

284279
self.inner_query(&portal_name, row_limit, params).map(move |(data, more_rows)| {
285280
LazyRows::new(self, data, portal_name, row_limit, more_rows, false, trans)

0 commit comments

Comments
 (0)