@@ -81,15 +81,10 @@ internal CouchDatabase(IFlurlClient flurlClient, CouchOptions options, QueryCont
8181 public async Task < TSource ? > FindAsync ( string docId , FindOptions options , CancellationToken cancellationToken = default )
8282 {
8383 IFlurlRequest request = NewRequest ( )
84+ . WithHeader ( "Accept" , "application/json" )
8485 . AppendPathSegment ( Uri . EscapeDataString ( docId ) ) ;
8586
86- if ( options . Conflicts )
87- request = request . SetQueryParam ( "conflicts" , "true" ) ;
88-
89- if ( options . Rev != null )
90- request = request . SetQueryParam ( "rev" , options . Rev ) ;
91-
92- IFlurlResponse ? response = await request
87+ IFlurlResponse ? response = await SetFindOptions ( request , options )
9388 . AllowHttpStatus ( HttpStatusCode . NotFound )
9489 . GetAsync ( cancellationToken )
9590 . ConfigureAwait ( false ) ;
@@ -512,6 +507,7 @@ private async Task UpdateAttachments(TSource document, CancellationToken cancell
512507 public async Task < ChangesFeedResponse < TSource > > GetChangesAsync ( ChangesFeedOptions ? options = null , ChangesFeedFilter ? filter = null , CancellationToken cancellationToken = default )
513508 {
514509 IFlurlRequest request = NewRequest ( )
510+ . WithHeader ( "Accept" , "application/json" )
515511 . AppendPathSegment ( "_changes" ) ;
516512
517513 if ( options ? . LongPoll == true )
@@ -524,11 +520,19 @@ public async Task<ChangesFeedResponse<TSource>> GetChangesAsync(ChangesFeedOptio
524520 request = request . ApplyQueryParametersOptions ( options ) ;
525521 }
526522
527- return filter == null
523+ ChangesFeedResponse < TSource > ? response = filter == null
528524 ? await request . GetJsonAsync < ChangesFeedResponse < TSource > > ( cancellationToken )
529525 . ConfigureAwait ( false )
530526 : await request . QueryWithFilterAsync < TSource > ( _queryProvider , filter , cancellationToken )
531527 . ConfigureAwait ( false ) ;
528+
529+ if ( string . IsNullOrWhiteSpace ( _discriminator ) )
530+ {
531+ return response ;
532+ }
533+
534+ response . Results = response . Results . Where ( result => result . Document . SplitDiscriminator == _discriminator ) . ToArray ( ) ;
535+ return response ;
532536 }
533537
534538 /// <inheritdoc />
@@ -538,6 +542,7 @@ public async IAsyncEnumerable<ChangesFeedResponseResult<TSource>> GetContinuousC
538542 var infiniteTimeout = TimeSpan . FromMilliseconds ( Timeout . Infinite ) ;
539543 IFlurlRequest request = NewRequest ( )
540544 . WithTimeout ( infiniteTimeout )
545+ . WithHeader ( "Accept" , "application/json" )
541546 . AppendPathSegment ( "_changes" )
542547 . SetQueryParam ( "feed" , "continuous" ) ;
543548
@@ -546,29 +551,45 @@ public async IAsyncEnumerable<ChangesFeedResponseResult<TSource>> GetContinuousC
546551 request = request . ApplyQueryParametersOptions ( options ) ;
547552 }
548553
549- await using Stream stream = filter == null
550- ? await request . GetStreamAsync ( cancellationToken , HttpCompletionOption . ResponseHeadersRead )
551- . ConfigureAwait ( false )
552- : await request . QueryContinuousWithFilterAsync < TSource > ( _queryProvider , filter , cancellationToken )
553- . ConfigureAwait ( false ) ;
554+ var lastSequence = options ? . Since ?? "0" ;
554555
555- await foreach ( var line in stream . ReadLinesAsync ( cancellationToken ) )
556+ do
556557 {
557- if ( string . IsNullOrEmpty ( line ) )
558- {
559- continue ;
560- }
558+ await using Stream stream = filter == null
559+ ? await request . GetStreamAsync ( cancellationToken , HttpCompletionOption . ResponseHeadersRead )
560+ . ConfigureAwait ( false )
561+ : await request . QueryContinuousWithFilterAsync < TSource > ( _queryProvider , filter , cancellationToken )
562+ . ConfigureAwait ( false ) ;
561563
562- MatchCollection matches = _feedChangeLineStartPattern . Matches ( line ) ;
563- for ( var i = 0 ; i < matches . Count ; i ++ )
564+ await foreach ( var line in stream . ReadLinesAsync ( cancellationToken ) )
564565 {
565- var startIndex = matches [ i ] . Index ;
566- var endIndex = i < matches . Count - 1 ? matches [ i + 1 ] . Index : line . Length ;
567- var lineLength = endIndex - startIndex ;
568- var substring = line . Substring ( startIndex , lineLength ) ;
569- yield return JsonConvert . DeserializeObject < ChangesFeedResponseResult < TSource > > ( substring ) ;
566+ if ( string . IsNullOrEmpty ( line ) )
567+ {
568+ continue ;
569+ }
570+
571+ MatchCollection matches = _feedChangeLineStartPattern . Matches ( line ) ;
572+ for ( var i = 0 ; i < matches . Count ; i ++ )
573+ {
574+ var startIndex = matches [ i ] . Index ;
575+ var endIndex = i < matches . Count - 1 ? matches [ i + 1 ] . Index : line . Length ;
576+ var lineLength = endIndex - startIndex ;
577+ var substring = line . Substring ( startIndex , lineLength ) ;
578+ ChangesFeedResponseResult < TSource > ? result =
579+ JsonConvert . DeserializeObject < ChangesFeedResponseResult < TSource > > ( substring ) ;
580+ if ( string . IsNullOrWhiteSpace ( _discriminator ) ||
581+ result . Document . SplitDiscriminator == _discriminator )
582+ {
583+ lastSequence = result . Seq ;
584+ yield return result ;
585+ }
586+ }
570587 }
571- }
588+
589+ // stream broke, pick up listening after last successful processed sequence
590+ request = request . SetQueryParam ( "since" , lastSequence ) ;
591+
592+ } while ( ! cancellationToken . IsCancellationRequested ) ;
572593 }
573594
574595 #endregion
@@ -788,6 +809,34 @@ public async Task<CouchDatabaseInfo> GetInfoAsync(CancellationToken cancellation
788809 . ConfigureAwait ( false ) ;
789810 }
790811
812+ /// <inheritdoc />
813+ public async Task < int > GetRevisionLimitAsync ( CancellationToken cancellationToken = default )
814+ {
815+ return Convert . ToInt32 ( await NewRequest ( )
816+ . AppendPathSegment ( "_revs_limit" )
817+ . GetStringAsync ( cancellationToken )
818+ . SendRequestAsync ( )
819+ . ConfigureAwait ( false ) ) ;
820+ }
821+
822+ /// <inheritdoc />
823+ public async Task SetRevisionLimitAsync ( int limit , CancellationToken cancellationToken = default )
824+ {
825+ using var content = new StringContent ( limit . ToString ( ) ) ;
826+
827+ OperationResult result = await NewRequest ( )
828+ . AppendPathSegment ( "_revs_limit" )
829+ . PutAsync ( content , cancellationToken )
830+ . ReceiveJson < OperationResult > ( )
831+ . SendRequestAsync ( )
832+ . ConfigureAwait ( false ) ;
833+
834+ if ( ! result . Ok )
835+ {
836+ throw new CouchException ( "Something wrong happened while updating the revision limit." ) ;
837+ }
838+ }
839+
791840 #endregion
792841
793842 #region Override
@@ -830,6 +879,64 @@ internal IndexBuilder<TSource> NewIndexBuilder(
830879 return builder ;
831880 }
832881
882+ private static IFlurlRequest SetFindOptions ( IFlurlRequest request , FindOptions options )
883+ {
884+ if ( options . Attachments )
885+ {
886+ request = request . SetQueryParam ( "attachments" , "true" ) ;
887+ }
888+ if ( options . AttachmentsEncodingInfo )
889+ {
890+ request = request . SetQueryParam ( "att_encoding_info" , "true" ) ;
891+ }
892+ if ( options . AttachmentsSince != null && options . AttachmentsSince . Any ( ) )
893+ {
894+ request = request . SetQueryParam ( "att_encoding_info" , options . AttachmentsSince ) ;
895+ }
896+ if ( options . Conflicts )
897+ {
898+ request = request . SetQueryParam ( "conflicts" , "true" ) ;
899+ }
900+ if ( options . DeleteConflicts )
901+ {
902+ request = request . SetQueryParam ( "deleted_conflicts" , "true" ) ;
903+ }
904+ if ( options . DeleteConflicts )
905+ {
906+ request = request . SetQueryParam ( "deleted_conflicts" , "true" ) ;
907+ }
908+ if ( options . Latest )
909+ {
910+ request = request . SetQueryParam ( "latest" , "true" ) ;
911+ }
912+ if ( options . LocalSequence )
913+ {
914+ request = request . SetQueryParam ( "local_seq" , "true" ) ;
915+ }
916+ if ( options . Meta )
917+ {
918+ request = request . SetQueryParam ( "meta" , "true" ) ;
919+ }
920+ if ( options . OpenRevisions != null && options . OpenRevisions . Any ( ) )
921+ {
922+ request = request . SetQueryParam ( "open_revs" , options . AttachmentsSince ) ;
923+ }
924+ if ( options . Revision != null )
925+ {
926+ request = request . SetQueryParam ( "rev" , options . Revision ) ;
927+ }
928+ if ( options . Revisions )
929+ {
930+ request = request . SetQueryParam ( "revs" , "true" ) ;
931+ }
932+ if ( options . RevisionsInfo )
933+ {
934+ request = request . SetQueryParam ( "revs_info" , "true" ) ;
935+ }
936+
937+ return request ;
938+ }
939+
833940 #endregion
834941 }
835942}
0 commit comments