%PDF- %PDF-
Direktori : /home/opti/optisoftcom-new/perl/usr/lib/perl5/MongoDB/ |
Current File : /home/opti/optisoftcom-new/perl/usr/lib/perl5/MongoDB/ChangeStream.pm |
# Copyright 2018 - present MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. use strict; use warnings; package MongoDB::ChangeStream; # ABSTRACT: A stream providing update information for collections. use version; our $VERSION = 'v2.0.2'; use Moo; use Try::Tiny; use MongoDB::Cursor; use MongoDB::Op::_ChangeStream; use MongoDB::Error; use Safe::Isa; use BSON::Timestamp; use MongoDB::_Types qw( MongoDBCollection ArrayOfHashRef Boolish BSONTimestamp ClientSession ); use Types::Standard qw( InstanceOf HashRef Maybe Str Num ); use namespace::clean -except => 'meta'; has _result => ( is => 'rw', isa => InstanceOf['MongoDB::QueryResult'], init_arg => undef, ); has _client => ( is => 'ro', isa => InstanceOf['MongoDB::MongoClient'], init_arg => 'client', required => 1, ); has _op_args => ( is => 'ro', isa => HashRef, init_arg => 'op_args', required => 1, ); has _pipeline => ( is => 'ro', isa => ArrayOfHashRef, init_arg => 'pipeline', required => 1, ); has _full_document => ( is => 'ro', isa => Str, init_arg => 'full_document', predicate => '_has_full_document', ); has _resume_after => ( is => 'ro', init_arg => 'resume_after', predicate => '_has_resume_after', ); has _all_changes_for_cluster => ( is => 'ro', isa => Boolish, init_arg => 'all_changes_for_cluster', default => sub { 0 }, ); has _start_at_operation_time => ( is => 'ro', isa => BSONTimestamp, init_arg => 'start_at_operation_time', predicate => '_has_start_at_operation_time', coerce => sub { ref($_[0]) ? $_[0] : BSON::Timestamp->new(seconds => $_[0]) }, ); has _session => ( is => 'ro', isa => Maybe[ClientSession], init_arg => 'session', ); has _options => ( is => 'ro', isa => HashRef, init_arg => 'options', default => sub { {} }, ); has _max_await_time_ms => ( is => 'ro', isa => Num, init_arg => 'max_await_time_ms', predicate => '_has_max_await_time_ms', ); has _last_operation_time => ( is => 'rw', init_arg => undef, predicate => '_has_last_operation_time', ); has _last_resume_token => ( is => 'rw', init_arg => undef, predicate => '_has_last_resume_token', ); sub BUILD { my ($self) = @_; # starting point is construction time instead of first next call $self->_execute_query; } sub _execute_query { my ($self) = @_; my $resume_opt = {}; # seen prior results, continuing after last resume token if ($self->_has_last_resume_token) { $resume_opt->{resume_after} = $self->_last_resume_token; } # no results yet, but we have operation time from prior query elsif ($self->_has_last_operation_time) { $resume_opt->{start_at_operation_time} = $self->_last_operation_time; } # no results and no prior operation time, send specified options else { $resume_opt->{start_at_operation_time} = $self->_start_at_operation_time if $self->_has_start_at_operation_time; $resume_opt->{resume_after} = $self->_resume_after if $self->_has_resume_after; } my $op = MongoDB::Op::_ChangeStream->new( pipeline => $self->_pipeline, all_changes_for_cluster => $self->_all_changes_for_cluster, session => $self->_session, options => $self->_options, client => $self->_client, $self->_has_full_document ? (full_document => $self->_full_document) : (), $self->_has_max_await_time_ms ? (maxAwaitTimeMS => $self->_max_await_time_ms) : (), %$resume_opt, %{ $self->_op_args }, ); my $res = $self->_client->send_read_op($op); $self->_result($res->{result}); $self->_last_operation_time($res->{operationTime}) if exists $res->{operationTime}; } #pod =head1 STREAM METHODS #pod #pod =cut #pod =head2 next #pod #pod $change_stream = $collection->watch(...); #pod $change = $change_stream->next; #pod #pod Waits for the next change in the collection and returns it. #pod #pod B<Note>: This method will wait for the amount of milliseconds passed #pod as C<maxAwaitTimeMS> to L<MongoDB::Collection/watch> or the server's #pod default wait-time. It will not wait indefinitely. #pod #pod =cut sub next { my ($self) = @_; my $change; my $retried; while (1) { last if try { $change = $self->_result->next; 1 # successfully fetched result } catch { my $error = $_; if ( not($retried) and $error->$_isa('MongoDB::Error') and $error->_is_resumable ) { $retried = 1; $self->_execute_query; } else { die $error; } 0 # failed, cursor was rebuilt }; } # this differs from drivers that block indefinitely. we have to # deal with the situation where no results are available. if (not defined $change) { return undef; ## no critic } if (exists $change->{_id}) { $self->_last_resume_token($change->{_id}); return $change; } else { MongoDB::InvalidOperationError->throw( "Cannot provide resume functionality when the ". "resume token is missing"); } } 1; __END__ =pod =encoding UTF-8 =head1 NAME MongoDB::ChangeStream - A stream providing update information for collections. =head1 VERSION version v2.0.2 =head1 SYNOPSIS $stream = $collection->watch( $pipeline, $options ); while(1) { # This inner loop will only iterate until there are no more # changes available. while (my $change = $stream->next) { ... } } =head1 DESCRIPTION This class models change stream results as returned by the L<MongoDB::Collection/watch> method. =head1 STREAM METHODS =head2 next $change_stream = $collection->watch(...); $change = $change_stream->next; Waits for the next change in the collection and returns it. B<Note>: This method will wait for the amount of milliseconds passed as C<maxAwaitTimeMS> to L<MongoDB::Collection/watch> or the server's default wait-time. It will not wait indefinitely. =head1 SEE ALSO The L<Change Streams manual section|https://docs.mongodb.com/manual/changeStreams/>. The L<Change Streams specification|https://github.com/mongodb/specifications/blob/master/source/change-streams.rst>. =head1 AUTHORS =over 4 =item * David Golden <david@mongodb.com> =item * Rassi <rassi@mongodb.com> =item * Mike Friedman <friedo@friedo.com> =item * Kristina Chodorow <k.chodorow@gmail.com> =item * Florian Ragwitz <rafl@debian.org> =back =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2018 by MongoDB, Inc. This is free software, licensed under: The Apache License, Version 2.0, January 2004 =cut