MongoDB

 view release on metacpan or  search on metacpan

lib/MongoDB/Op/_Query.pm  view on Meta::CPAN


    if ( defined $self->{options}{collation} and !$link->supports_collation ) {
        MongoDB::UsageError->throw(
            "MongoDB host '" . $link->address . "' doesn't support collation" );
    }

    my $res =
        $link->supports_query_commands
      ? $self->_command_query( $link, $topology )
      : $self->_legacy_query( $link, $topology );

    return $res;
}

sub _command_query {
    my ( $self, $link, $topology ) = @_;

    my $op = MongoDB::Op::_Command->_new(
        db_name             => $self->db_name,
        query               => $self->_as_command,
        query_flags         => {},
        read_preference     => $self->read_preference,
        bson_codec          => $self->bson_codec,
        session             => $self->session,
        monitoring_callback => $self->monitoring_callback,
    );
    my $res = $op->execute( $link, $topology );

    return $self->_build_result_from_cursor($res);
}

sub _legacy_query {
    my ( $self, $link, $topology ) = @_;

    my $opts = $self->{options};

    my $query_flags = {
        tailable => ( $opts->{cursorType} =~ /^tailable/ ? 1 : 0 ),
        await_data => $opts->{cursorType} eq 'tailable_await',
        immortal   => $opts->{noCursorTimeout},
        partial    => $opts->{allowPartialResults},
    };

    my $query = $self->_as_query_document($opts);

    my $full_name = $self->full_name;

    # rules for calculating initial batch size
    my $limit      = $opts->{limit}     // 0;
    my $batch_size = $opts->{batchSize} // 0;
    my $n_to_return =
        $limit == 0      ? $batch_size
      : $batch_size == 0 ? $limit
      : $limit < 0       ? $limit
      :                    min( $limit, $batch_size );

    my $proj =
      $opts->{projection} ? $self->bson_codec->encode_one( $opts->{projection} ) : undef;

    # $query is passed as a reference because it *may* be replaced
    $self->_apply_op_query_read_prefs( $link, $topology, $query_flags, \$query );

    my $filter = $self->bson_codec->encode_one($query);

    my ( $op_bson, $request_id ) =
      MongoDB::_Protocol::write_query( $full_name, $filter, $proj, $opts->{skip},
        $n_to_return, $query_flags );

    my $result =
      $self->_query_and_receive( $link, $op_bson, $request_id, $self->bson_codec );

    my $class =
      $self->has_post_filter ? "MongoDB::QueryResult::Filtered" : "MongoDB::QueryResult";

    return $class->_new(
        _client       => $self->client,
        _address      => $link->address,
        _full_name    => $full_name,
        _bson_codec   => $self->bson_codec,
        _batch_size   => $n_to_return,
        _cursor_at    => 0,
        _limit        => $limit,
        _cursor_id    => $result->{cursor_id},
        _cursor_start => $result->{starting_from},
        _cursor_flags => $result->{flags} || {},
        _cursor_num   => $result->{number_returned},
        _docs         => $result->{docs},
        _post_filter  => $self->post_filter,
    );
}

# awful hack: avoid calling into boolean to get true/false
my $TRUE  = boolean::true();
my $FALSE = boolean::false();

sub _as_query_document {
    my ($self, $opts) = @_;

    # Reconstruct query modifiers style from options.  However, we only
    # apply $maxTimeMS if we're not running a command via OP_QUERY against
    # the '$cmd' collection.  For commands, we expect maxTimeMS to be in
    # the command itself.
    my $query = {
        ( defined $opts->{comment}      ? ( '$comment'     => $opts->{comment} )      : () ),
        ( defined $opts->{hint}         ? ( '$hint'        => $opts->{hint} )         : () ),
        ( defined $opts->{max}          ? ( '$max'         => $opts->{max} )          : () ),
        ( defined $opts->{min}          ? ( '$min'         => $opts->{min} )          : () ),
        ( defined $opts->{sort}         ? ( '$orderby'     => $opts->{sort} )         : () ),
        ( defined $opts->{maxScan}      ? ( '$maxScan'     => $opts->{maxScan} )      : () ),
        ( defined $opts->{returnKey}    ? ( '$returnKey'   => $opts->{returnKey} )    : () ),
        ( defined $opts->{showRecordId} ? ( '$showDiskLoc' => $opts->{showRecordId} ) : () ),
        ( defined $opts->{snapshot}     ? ( '$snapshot'    => $opts->{snapshot} )     : () ),
        (
              ( defined $opts->{maxTimeMS} && $self->coll_name !~ /\A\$cmd/ )
            ? ( '$maxTimeMS' => $opts->{maxTimeMS} )
            : ()
        ),
        # Not a user-provided option: this is only set by MongoDB::Op::_Explain
        # for legacy $explain support
        ( defined $opts->{explain} ? ( '$explain' => $TRUE ) : () ),
        ( '$query' => ( $self->filter || {} ) ),



( run in 0.492 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )