@@ -128,16 +128,20 @@ use crate::copy_out;
128
128
use crate :: connection:: RequestMessages ;
129
129
use crate :: types:: Type ;
130
130
use crate :: { simple_query, Client , Error , SimpleQueryStream , SimpleQueryMessage } ;
131
- use bytes:: BytesMut ;
131
+ use bytes:: { Bytes , BytesMut } ;
132
132
use fallible_iterator:: FallibleIterator ;
133
133
use futures:: { ready, Stream , TryStreamExt } ;
134
134
use pin_project:: { pin_project, pinned_drop} ;
135
135
use postgres_types:: PgLsn ;
136
136
use postgres_protocol:: escape:: { escape_identifier, escape_literal} ;
137
- use postgres_protocol:: message:: backend:: { Message , ReplicationMessage , RowDescriptionBody } ;
137
+ use postgres_protocol:: message:: backend:: {
138
+ Message , Parse , ReplicationMessage , RowDescriptionBody ,
139
+ } ;
138
140
use postgres_protocol:: message:: frontend;
141
+ use postgres_protocol:: replication:: DecodingPlugin ;
142
+
139
143
use std:: io;
140
- use std:: marker:: PhantomPinned ;
144
+ use std:: marker:: { PhantomData , PhantomPinned } ;
141
145
use std:: path:: { Path , PathBuf } ;
142
146
use std:: pin:: Pin ;
143
147
use std:: str:: from_utf8;
@@ -495,11 +499,11 @@ impl ReplicationClient {
495
499
/// Plugins](https://www.postgresql.org/docs/current/logicaldecoding-output-plugin.html)).
496
500
/// * `snapshot_mode`: Decides what to do with the snapshot
497
501
/// created during logical slot initialization.
498
- pub async fn create_logical_replication_slot (
502
+ pub async fn create_logical_replication_slot < P : DecodingPlugin > (
499
503
& mut self ,
500
504
slot_name : & str ,
501
505
temporary : bool ,
502
- plugin_name : & str ,
506
+ plugin : & P ,
503
507
snapshot_mode : Option < SnapshotMode > ,
504
508
) -> Result < CreateReplicationSlotResponse , Error > {
505
509
let temporary_str = if temporary { " TEMPORARY" } else { "" } ;
@@ -512,7 +516,7 @@ impl ReplicationClient {
512
516
"CREATE_REPLICATION_SLOT {}{} LOGICAL {}{}" ,
513
517
escape_identifier( slot_name) ,
514
518
temporary_str,
515
- escape_identifier( plugin_name ) ,
519
+ escape_identifier( plugin . name ( ) ) ,
516
520
snapshot_str
517
521
) ;
518
522
let mut responses = self . send ( & command) . await ?;
@@ -584,7 +588,7 @@ impl ReplicationClient {
584
588
slot_name : Option < & str > ,
585
589
lsn : PgLsn ,
586
590
timeline_id : Option < u32 > ,
587
- ) -> Result < Pin < Box < ReplicationStream < ' a > > > , Error > {
591
+ ) -> Result < Pin < Box < ReplicationStream < ' a , Bytes > > > , Error > {
588
592
let slot = match slot_name {
589
593
Some ( name) => format ! ( " SLOT {}" , escape_identifier( name) ) ,
590
594
None => String :: from ( "" ) ,
@@ -614,13 +618,14 @@ impl ReplicationClient {
614
618
/// * `lsn`: The starting WAL location.
615
619
/// * `options`: (name, value) pairs of options passed to the
616
620
/// slot's logical decoding plugin.
617
- pub async fn start_logical_replication < ' a > (
621
+ pub async fn start_logical_replication < ' a , P : DecodingPlugin > (
618
622
& ' a mut self ,
619
623
slot_name : & str ,
620
624
lsn : PgLsn ,
621
- options : & [ ( & str , & str ) ] ,
622
- ) -> Result < Pin < Box < ReplicationStream < ' a > > > , Error > {
625
+ plugin : & P ,
626
+ ) -> Result < Pin < Box < ReplicationStream < ' a , P :: Message > > > , Error > {
623
627
let slot = format ! ( " SLOT {}" , escape_identifier( slot_name) ) ;
628
+ let options = plugin. options ( ) ;
624
629
let options_string = if !options. is_empty ( ) {
625
630
format ! (
626
631
" ({})" ,
@@ -678,10 +683,10 @@ impl ReplicationClient {
678
683
Ok ( responses)
679
684
}
680
685
681
- async fn start_replication < ' a > (
686
+ async fn start_replication < ' a , D > (
682
687
& ' a mut self ,
683
688
command : String ,
684
- ) -> Result < Pin < Box < ReplicationStream < ' a > > > , Error > {
689
+ ) -> Result < Pin < Box < ReplicationStream < ' a , D > > > , Error > {
685
690
let mut copyboth_received = false ;
686
691
let mut replication_response: Option < ReplicationResponse > = None ;
687
692
let mut responses = self . send ( & command) . await ?;
@@ -717,6 +722,7 @@ impl ReplicationClient {
717
722
copydone_sent : false ,
718
723
copydone_received : false ,
719
724
replication_response : replication_response,
725
+ _phantom_data : PhantomData ,
720
726
_phantom_pinned : PhantomPinned ,
721
727
} ) )
722
728
}
@@ -752,18 +758,19 @@ impl ReplicationClient {
752
758
/// [stop_replication()](ReplicationStream::stop_replication()) will
753
759
/// return a response tuple.
754
760
#[ pin_project( PinnedDrop ) ]
755
- pub struct ReplicationStream < ' a > {
761
+ pub struct ReplicationStream < ' a , D > {
756
762
rclient : & ' a mut ReplicationClient ,
757
763
responses : Responses ,
758
764
copyboth_received : bool ,
759
765
copydone_sent : bool ,
760
766
copydone_received : bool ,
761
767
replication_response : Option < ReplicationResponse > ,
768
+ _phantom_data : PhantomData < D > ,
762
769
#[ pin]
763
770
_phantom_pinned : PhantomPinned ,
764
771
}
765
772
766
- impl < ' a > ReplicationStream < ' a > {
773
+ impl < ' a , D > ReplicationStream < ' a , D > {
767
774
/// Send standby update to server.
768
775
pub async fn standby_status_update (
769
776
self : Pin < & mut Self > ,
@@ -855,8 +862,8 @@ impl<'a> ReplicationStream<'a> {
855
862
}
856
863
}
857
864
858
- impl Stream for ReplicationStream < ' _ > {
859
- type Item = Result < ReplicationMessage , Error > ;
865
+ impl < D : Parse > Stream for ReplicationStream < ' _ , D > {
866
+ type Item = Result < ReplicationMessage < D > , Error > ;
860
867
861
868
fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
862
869
let this = self . project ( ) ;
@@ -872,7 +879,7 @@ impl Stream for ReplicationStream<'_> {
872
879
assert ! ( !* this. copydone_received) ;
873
880
match ready ! ( this. responses. poll_next( cx) ?) {
874
881
Message :: CopyData ( body) => {
875
- let r = ReplicationMessage :: parse ( & body. into_bytes ( ) ) ;
882
+ let r = ReplicationMessage :: parse ( & mut body. into_bytes ( ) ) ;
876
883
Poll :: Ready ( Some ( r. map_err ( Error :: parse) ) )
877
884
}
878
885
Message :: CopyDone => {
@@ -887,7 +894,7 @@ impl Stream for ReplicationStream<'_> {
887
894
}
888
895
889
896
#[ pinned_drop]
890
- impl PinnedDrop for ReplicationStream < ' _ > {
897
+ impl < D > PinnedDrop for ReplicationStream < ' _ , D > {
891
898
fn drop ( mut self : Pin < & mut Self > ) {
892
899
let this = self . project ( ) ;
893
900
if * this. copyboth_received && !* this. copydone_sent {
0 commit comments