@@ -4,7 +4,7 @@ use postgres_protocol;
4
4
use postgres_protocol:: message:: backend:: Message ;
5
5
use postgres_protocol:: message:: frontend;
6
6
use std:: collections:: HashMap ;
7
- use std:: sync:: Arc ;
7
+ use std:: sync:: { Arc , Weak } ;
8
8
9
9
use disconnected;
10
10
use error:: { self , Error } ;
@@ -15,67 +15,120 @@ use proto::query::QueryStream;
15
15
use proto:: statement:: Statement ;
16
16
use types:: { IsNull , Oid , ToSql , Type } ;
17
17
18
- pub struct PendingRequest {
19
- sender : mpsc:: UnboundedSender < Request > ,
20
- messages : Result < Vec < u8 > , Error > ,
21
- }
18
+ pub struct PendingRequest ( Result < Vec < u8 > , Error > ) ;
22
19
23
- impl PendingRequest {
24
- pub fn send ( self ) -> Result < mpsc:: Receiver < Message > , Error > {
25
- let messages = self . messages ?;
26
- let ( sender, receiver) = mpsc:: channel ( 0 ) ;
27
- self . sender
28
- . unbounded_send ( Request { messages, sender } )
29
- . map ( |_| receiver)
30
- . map_err ( |_| disconnected ( ) )
20
+ pub struct WeakClient ( Weak < Inner > ) ;
21
+
22
+ impl WeakClient {
23
+ pub fn upgrade ( & self ) -> Option < Client > {
24
+ self . 0 . upgrade ( ) . map ( Client )
31
25
}
32
26
}
33
27
34
- pub struct State {
35
- pub types : HashMap < Oid , Type > ,
36
- pub typeinfo_query : Option < Statement > ,
37
- pub typeinfo_enum_query : Option < Statement > ,
38
- pub typeinfo_composite_query : Option < Statement > ,
28
+ struct State {
29
+ types : HashMap < Oid , Type > ,
30
+ typeinfo_query : Option < Statement > ,
31
+ typeinfo_enum_query : Option < Statement > ,
32
+ typeinfo_composite_query : Option < Statement > ,
39
33
}
40
34
41
- #[ derive( Clone ) ]
42
- pub struct Client {
43
- pub state : Arc < Mutex < State > > ,
35
+ struct Inner {
36
+ state : Mutex < State > ,
44
37
sender : mpsc:: UnboundedSender < Request > ,
45
38
}
46
39
40
+ #[ derive( Clone ) ]
41
+ pub struct Client ( Arc < Inner > ) ;
42
+
47
43
impl Client {
48
44
pub fn new ( sender : mpsc:: UnboundedSender < Request > ) -> Client {
49
- Client {
50
- state : Arc :: new ( Mutex :: new ( State {
45
+ Client ( Arc :: new ( Inner {
46
+ state : Mutex :: new ( State {
51
47
types : HashMap :: new ( ) ,
52
48
typeinfo_query : None ,
53
49
typeinfo_enum_query : None ,
54
50
typeinfo_composite_query : None ,
55
- } ) ) ,
51
+ } ) ,
56
52
sender,
57
- }
53
+ } ) )
54
+ }
55
+
56
+ pub fn downgrade ( & self ) -> WeakClient {
57
+ WeakClient ( Arc :: downgrade ( & self . 0 ) )
58
+ }
59
+
60
+ pub fn cached_type ( & self , oid : Oid ) -> Option < Type > {
61
+ self . 0 . state . lock ( ) . types . get ( & oid) . cloned ( )
62
+ }
63
+
64
+ pub fn cache_type ( & self , ty : & Type ) {
65
+ self . 0 . state . lock ( ) . types . insert ( ty. oid ( ) , ty. clone ( ) ) ;
66
+ }
67
+
68
+ pub fn typeinfo_query ( & self ) -> Option < Statement > {
69
+ self . 0 . state . lock ( ) . typeinfo_query . clone ( )
70
+ }
71
+
72
+ pub fn set_typeinfo_query ( & self , statement : & Statement ) {
73
+ self . 0 . state . lock ( ) . typeinfo_query = Some ( statement. clone ( ) ) ;
58
74
}
59
75
60
- pub fn prepare ( & mut self , name : String , query : & str , param_types : & [ Type ] ) -> PrepareFuture {
76
+ pub fn typeinfo_enum_query ( & self ) -> Option < Statement > {
77
+ self . 0 . state . lock ( ) . typeinfo_enum_query . clone ( )
78
+ }
79
+
80
+ pub fn set_typeinfo_enum_query ( & self , statement : & Statement ) {
81
+ self . 0 . state . lock ( ) . typeinfo_enum_query = Some ( statement. clone ( ) ) ;
82
+ }
83
+
84
+ pub fn typeinfo_composite_query ( & self ) -> Option < Statement > {
85
+ self . 0 . state . lock ( ) . typeinfo_composite_query . clone ( )
86
+ }
87
+
88
+ pub fn set_typeinfo_composite_query ( & self , statement : & Statement ) {
89
+ self . 0 . state . lock ( ) . typeinfo_composite_query = Some ( statement. clone ( ) ) ;
90
+ }
91
+
92
+ pub fn send ( & self , request : PendingRequest ) -> Result < mpsc:: Receiver < Message > , Error > {
93
+ let messages = request. 0 ?;
94
+ let ( sender, receiver) = mpsc:: channel ( 0 ) ;
95
+ self . 0
96
+ . sender
97
+ . unbounded_send ( Request { messages, sender } )
98
+ . map ( |_| receiver)
99
+ . map_err ( |_| disconnected ( ) )
100
+ }
101
+
102
+ pub fn prepare ( & self , name : String , query : & str , param_types : & [ Type ] ) -> PrepareFuture {
61
103
let pending = self . pending ( |buf| {
62
104
frontend:: parse ( & name, query, param_types. iter ( ) . map ( |t| t. oid ( ) ) , buf) ?;
63
105
frontend:: describe ( b'S' , & name, buf) ?;
64
106
frontend:: sync ( buf) ;
65
107
Ok ( ( ) )
66
108
} ) ;
67
109
68
- PrepareFuture :: new ( pending , self . sender . clone ( ) , name , self . clone ( ) )
110
+ PrepareFuture :: new ( self . clone ( ) , pending , name )
69
111
}
70
112
71
- pub fn execute ( & mut self , statement : & Statement , params : & [ & ToSql ] ) -> ExecuteFuture {
113
+ pub fn execute ( & self , statement : & Statement , params : & [ & ToSql ] ) -> ExecuteFuture {
72
114
let pending = self . pending_execute ( statement, params) ;
73
- ExecuteFuture :: new ( pending, statement. clone ( ) )
115
+ ExecuteFuture :: new ( self . clone ( ) , pending, statement. clone ( ) )
74
116
}
75
117
76
- pub fn query ( & mut self , statement : & Statement , params : & [ & ToSql ] ) -> QueryStream {
118
+ pub fn query ( & self , statement : & Statement , params : & [ & ToSql ] ) -> QueryStream {
77
119
let pending = self . pending_execute ( statement, params) ;
78
- QueryStream :: new ( pending, statement. clone ( ) )
120
+ QueryStream :: new ( self . clone ( ) , pending, statement. clone ( ) )
121
+ }
122
+
123
+ pub fn close_statement ( & self , name : & str ) {
124
+ let mut buf = vec ! [ ] ;
125
+ frontend:: close ( b'S' , name, & mut buf) . expect ( "statement name not valid" ) ;
126
+ frontend:: sync ( & mut buf) ;
127
+ let ( sender, _) = mpsc:: channel ( 0 ) ;
128
+ let _ = self . 0 . sender . unbounded_send ( Request {
129
+ messages : buf,
130
+ sender,
131
+ } ) ;
79
132
}
80
133
81
134
fn pending_execute ( & self , statement : & Statement , params : & [ & ToSql ] ) -> PendingRequest {
@@ -109,9 +162,6 @@ impl Client {
109
162
F : FnOnce ( & mut Vec < u8 > ) -> Result < ( ) , Error > ,
110
163
{
111
164
let mut buf = vec ! [ ] ;
112
- PendingRequest {
113
- sender : self . sender . clone ( ) ,
114
- messages : messages ( & mut buf) . map ( |( ) | buf) ,
115
- }
165
+ PendingRequest ( messages ( & mut buf) . map ( |( ) | buf) )
116
166
}
117
167
}
0 commit comments