@@ -21,11 +21,9 @@ fn main() {
2121
2222 let jh = thread:: spawn ( move || {
2323 if let Ok ( ( s, _) ) = listener. accept ( ) {
24- let conn = postgres:: Connection :: connect (
25- "postgresql://postgres@localhost:5432" ,
26- postgres:: TlsMode :: None ,
27- )
28- . unwrap ( ) ;
24+ let conn =
25+ postgres:: Client :: connect ( "postgresql://postgres@localhost:5432" , postgres:: NoTls )
26+ . unwrap ( ) ;
2927 MysqlIntermediary :: run_on_tcp ( Postgres :: new ( conn) , s) . unwrap ( ) ;
3028 }
3129 } ) ;
@@ -91,28 +89,46 @@ fn main() {
9189
9290// this is where the proxy server implementation starts
9391
94- struct Prepared < ' a > {
95- stmt : postgres:: stmt :: Statement < ' a > ,
92+ struct Prepared {
93+ stmt : postgres:: Statement ,
9694 params : Vec < Column > ,
9795}
9896
9997struct Postgres {
100- connection : postgres:: Connection ,
98+ connection : postgres:: Client ,
10199 // NOTE: not *actually* static, but tied to our connection's lifetime.
102- prepared : Slab < Prepared < ' static > > ,
100+ prepared : Slab < Prepared > ,
103101}
104102
105103impl Postgres {
106- fn new ( c : postgres:: Connection ) -> Self {
104+ fn new ( c : postgres:: Client ) -> Self {
107105 Postgres {
108106 connection : c,
109107 prepared : Slab :: new ( ) ,
110108 }
111109 }
112110}
113111
112+ #[ derive( Debug ) ]
113+ enum Error {
114+ Pg ( postgres:: Error ) ,
115+ Io ( io:: Error ) ,
116+ }
117+
118+ impl From < io:: Error > for Error {
119+ fn from ( e : io:: Error ) -> Self {
120+ Error :: Io ( e)
121+ }
122+ }
123+
124+ impl From < postgres:: Error > for Error {
125+ fn from ( e : postgres:: Error ) -> Self {
126+ Error :: Pg ( e)
127+ }
128+ }
129+
114130impl < W : io:: Write > MysqlShim < W > for Postgres {
115- type Error = postgres :: Error ;
131+ type Error = Error ;
116132
117133 fn on_prepare ( & mut self , query : & str , info : StatementMetaWriter < W > ) -> Result < ( ) , Self :: Error > {
118134 match self . connection . prepare ( query) {
@@ -122,7 +138,7 @@ impl<W: io::Write> MysqlShim<W> for Postgres {
122138 // client, which requires translating between psql and mysql types.
123139 use std:: mem;
124140 let params: Vec < _ > = stmt
125- . param_types ( )
141+ . params ( )
126142 . into_iter ( )
127143 . map ( |t| {
128144 let ct = p2mt ( t) ;
@@ -165,13 +181,14 @@ impl<W: io::Write> MysqlShim<W> for Postgres {
165181 info. reply ( id as u32 , & stmt. params , & columns) ?;
166182 Ok ( ( ) )
167183 }
184+
168185 Err ( e) => {
169- if let Some ( db) = e. as_db ( ) {
170- info. error ( ErrorKind :: ER_NO , db. message . as_bytes ( ) ) ?;
186+ if let Some ( db) = e. as_db_error ( ) {
187+ info. error ( ErrorKind :: ER_NO , db. message ( ) . as_bytes ( ) ) ?;
171188 return Ok ( ( ) ) ;
172189 }
173190
174- Err ( e)
191+ Err ( e. into ( ) )
175192 }
176193 }
177194 }
@@ -190,7 +207,7 @@ impl<W: io::Write> MysqlShim<W> for Postgres {
190207 // we can only do that by first boxing all the values (so they can be kept in a
191208 // single vec), and then collecting a *second* vec with references to those, and
192209 // *then* take a slice of that vec.
193- let args: Vec < Box < dyn postgres:: types:: ToSql > > = ps
210+ let args: Vec < Box < dyn postgres:: types:: ToSql + Sync > > = ps
194211 . into_iter ( )
195212 . map ( |p| match p. coltype {
196213 ColumnType :: MYSQL_TYPE_SHORT => {
@@ -222,7 +239,7 @@ impl<W: io::Write> MysqlShim<W> for Postgres {
222239
223240 // lazy_query unfortunately gets us into all sorts of lifetime trouble it seems...
224241 // so we do it eagerly instead.
225- answer_rows ( results, stmt . query ( & args[ ..] ) )
242+ answer_rows ( results, self . connection . query ( stmt , & args[ ..] ) )
226243 }
227244 }
228245 }
@@ -247,49 +264,59 @@ impl Drop for Postgres {
247264/// Take a set of rows from PostgreSQL and re-encode them as MySQL rows
248265fn answer_rows < W : io:: Write > (
249266 results : QueryResultWriter < W > ,
250- rows : postgres :: Result < postgres:: rows :: Rows > ,
251- ) -> Result < ( ) , postgres :: Error > {
267+ rows : Result < Vec < postgres:: Row > , postgres :: Error > ,
268+ ) -> Result < ( ) , Error > {
252269 match rows {
253270 Ok ( rows) => {
254- let cols: Vec < _ > = rows
255- . columns ( )
256- . into_iter ( )
257- . map ( |c| {
258- let t = c. type_ ( ) ;
259- let ct = p2mt ( t) ;
260- Column {
261- table : t. schema ( ) . to_owned ( ) ,
262- column : c. name ( ) . to_owned ( ) ,
263- coltype : ct,
264- colflags : ColumnFlags :: empty ( ) ,
265- }
266- } )
267- . collect ( ) ;
268-
269- let mut writer = results. start ( & cols) ?;
270- for row in & rows {
271- for ( c, col) in cols. iter ( ) . enumerate ( ) {
272- match col. coltype {
273- ColumnType :: MYSQL_TYPE_SHORT => writer. write_col ( row. get :: < _ , i16 > ( c) ) ?,
274- ColumnType :: MYSQL_TYPE_LONG => writer. write_col ( row. get :: < _ , i32 > ( c) ) ?,
275- ColumnType :: MYSQL_TYPE_LONGLONG => {
276- writer. write_col ( row. get :: < _ , i64 > ( c) ) ?
277- }
278- ColumnType :: MYSQL_TYPE_FLOAT => writer. write_col ( row. get :: < _ , f32 > ( c) ) ?,
279- ColumnType :: MYSQL_TYPE_DOUBLE => writer. write_col ( row. get :: < _ , f64 > ( c) ) ?,
280- ColumnType :: MYSQL_TYPE_STRING => {
281- writer. write_col ( row. get :: < _ , String > ( c) ) ?
271+ if let Some ( first) = rows. iter ( ) . next ( ) {
272+ let cols: Vec < _ > = first
273+ . columns ( )
274+ . into_iter ( )
275+ . map ( |c| {
276+ let t = c. type_ ( ) ;
277+ let ct = p2mt ( t) ;
278+ Column {
279+ table : t. schema ( ) . to_owned ( ) ,
280+ column : c. name ( ) . to_owned ( ) ,
281+ coltype : ct,
282+ colflags : ColumnFlags :: empty ( ) ,
282283 }
283- ct => unimplemented ! (
284- "don't know how to translate PostgreSQL \
284+ } )
285+ . collect ( ) ;
286+
287+ let mut writer = results. start ( & cols) ?;
288+ for row in & rows {
289+ for ( c, col) in cols. iter ( ) . enumerate ( ) {
290+ match col. coltype {
291+ ColumnType :: MYSQL_TYPE_SHORT => {
292+ writer. write_col ( row. get :: < _ , i16 > ( c) ) ?
293+ }
294+ ColumnType :: MYSQL_TYPE_LONG => {
295+ writer. write_col ( row. get :: < _ , i32 > ( c) ) ?
296+ }
297+ ColumnType :: MYSQL_TYPE_LONGLONG => {
298+ writer. write_col ( row. get :: < _ , i64 > ( c) ) ?
299+ }
300+ ColumnType :: MYSQL_TYPE_FLOAT => {
301+ writer. write_col ( row. get :: < _ , f32 > ( c) ) ?
302+ }
303+ ColumnType :: MYSQL_TYPE_DOUBLE => {
304+ writer. write_col ( row. get :: < _ , f64 > ( c) ) ?
305+ }
306+ ColumnType :: MYSQL_TYPE_STRING => {
307+ writer. write_col ( row. get :: < _ , String > ( c) ) ?
308+ }
309+ ct => unimplemented ! (
310+ "don't know how to translate PostgreSQL \
285311 argument type {:?} into MySQL value",
286- ct
287- ) ,
312+ ct
313+ ) ,
314+ }
288315 }
316+ writer. end_row ( ) ?;
289317 }
290- writer. end_row ( ) ?;
318+ writer. finish ( ) ?;
291319 }
292- writer. finish ( ) ?;
293320 }
294321 Err ( e) => {
295322 results. error ( ErrorKind :: ER_BAD_SLAVE , format ! ( "{:?}" , e) . as_bytes ( ) ) ?;
@@ -302,12 +329,12 @@ fn answer_rows<W: io::Write>(
302329fn p2mt ( t : & postgres:: types:: Type ) -> msql_srv:: ColumnType {
303330 if let postgres:: types:: Kind :: Simple = * t. kind ( ) {
304331 match postgres:: types:: Type :: from_oid ( t. oid ( ) ) {
305- Some ( postgres:: types:: INT2 ) => msql_srv:: ColumnType :: MYSQL_TYPE_SHORT ,
306- Some ( postgres:: types:: INT4 ) => msql_srv:: ColumnType :: MYSQL_TYPE_LONG ,
307- Some ( postgres:: types:: INT8 ) => msql_srv:: ColumnType :: MYSQL_TYPE_LONGLONG ,
308- Some ( postgres:: types:: FLOAT4 ) => msql_srv:: ColumnType :: MYSQL_TYPE_FLOAT ,
309- Some ( postgres:: types:: FLOAT8 ) => msql_srv:: ColumnType :: MYSQL_TYPE_DOUBLE ,
310- Some ( postgres:: types:: TEXT ) => msql_srv:: ColumnType :: MYSQL_TYPE_STRING ,
332+ Some ( postgres:: types:: Type :: INT2 ) => msql_srv:: ColumnType :: MYSQL_TYPE_SHORT ,
333+ Some ( postgres:: types:: Type :: INT4 ) => msql_srv:: ColumnType :: MYSQL_TYPE_LONG ,
334+ Some ( postgres:: types:: Type :: INT8 ) => msql_srv:: ColumnType :: MYSQL_TYPE_LONGLONG ,
335+ Some ( postgres:: types:: Type :: FLOAT4 ) => msql_srv:: ColumnType :: MYSQL_TYPE_FLOAT ,
336+ Some ( postgres:: types:: Type :: FLOAT8 ) => msql_srv:: ColumnType :: MYSQL_TYPE_DOUBLE ,
337+ Some ( postgres:: types:: Type :: TEXT ) => msql_srv:: ColumnType :: MYSQL_TYPE_STRING ,
311338 t => {
312339 unimplemented ! (
313340 "don't know how to translate PostgreSQL type {:?} to a MySQL type" ,
0 commit comments