123456789_123456789_123456789_123456789_123456789_

Class: Mongo::Operation::Result

Relationships & Source Files
Namespace Children
Modules:
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Forwardable
Instance Chain:
self, Enumerable
Inherits: Object
Defined in: lib/mongo/operation/result.rb,
lib/mongo/operation/shared/result/aggregatable.rb

Overview

Result wrapper for wire protocol replies.

An operation has zero or one replies. The only operations producing zero replies are unacknowledged writes; all other operations produce one reply. This class provides an object that can be operated on (for example, to check whether an operation succeeded) even when the operation did not produce a reply (in which case it is assumed to have succeeded).

Since:

  • 2.0.0

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(replies, connection_description = nil, connection_global_id = nil, context: nil, connection: nil) ⇒ Result

Initialize a new result.

For an unkacknowledged write, pass nil in replies.

For all other operations, replies must be a ::Mongo::Protocol::Message instance or an array containing a single ::Mongo::Protocol::Message instance.

Parameters:

  • replies (Protocol::Message | Array<Protocol::Message> | nil)

    The wire protocol replies.

  • connection_description (Server::Description | nil) (defaults to: nil)

    ::Mongo::Server description of the server that performed the operation that this result is for. This parameter is allowed to be nil for compatibility with existing mongo_kerberos library, but should always be not nil in the driver proper.

  • connection_global_id (Integer) (defaults to: nil)

    Global id of the connection on which the operation that this result is for was performed.

  • context (Operation::Context | nil)

    the context that was active when this result was produced.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 104

def initialize(replies, connection_description = nil, connection_global_id = nil, context: nil, connection: nil)
  @context = context

  return unless replies

  if replies.is_a?(Array)
    raise ArgumentError, "Only one (or zero) reply is supported, given #{replies.length}" if replies.length != 1

    reply = replies.first
  else
    reply = replies
  end
  unless reply.is_a?(Protocol::Message)
    raise ArgumentError, "Argument must be a Message instance, but is a #{reply.class}: #{reply.inspect}"
  end

  @replies = [ reply ]
  @connection_description = connection_description
  @connection_global_id = connection_global_id
  @connection = connection
end

Instance Attribute Details

#acknowledged?true, false (readonly)

Is the result acknowledged?

Returns:

  • (true, false)

    If the result is acknowledged.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 161

def acknowledged?
  !!@replies
end

#connection (readonly)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 149

attr_reader :connection

#connection_descriptionServer::Description (readonly)

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 135

attr_reader :connection_description

#connection_global_idObject (readonly)

Returns:

  • (Object)

    Global is of the connection that the operation was performed on that this result is for.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 141

attr_reader :connection_global_id

#contextOperation::Context | nil (readonly)

Returns:

  • (Operation::Context | nil)

    the operation context (if any) that was active when this result was produced.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 147

attr_reader :context

#ok?true, false (readonly)

Check the first document's ok field.

Examples:

Check the ok field.

result.ok?

Returns:

  • (true, false)

    If the command returned ok.

Since:

  • 2.1.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 309

def ok?
  # first_document[OK] is a float, and the server can return
  # ok as a BSON int32, BSON int64 or a BSON double.
  # The number 1 is exactly representable in a float, hence
  # 1.0 == 1 is going to perform correctly all of the time
  # (until the server returns something other than 1 for success, that is)
  first_document[OK] == 1
end

#query_failure?Boolean (readonly, private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 477

def query_failure?
  replies.first && (replies.first.query_failure? || replies.first.cursor_not_found?)
end

#repliesArray<Protocol::Message> (readonly)

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 129

attr_reader :replies

#successful?true, false (readonly)

Note:

If the write was unacknowledged, then this will always return true.

If the result was a command then determine if it was considered a success.

Examples:

Was the command successful?

result.successful?

Returns:

  • (true, false)

    If the command was successful.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 290

def successful?
  return true unless acknowledged?

  if first_document.has_key?(OK)
    ok? && parser.message.empty?
  else
    !query_failure? && parser.message.empty?
  end
end

#write_concern_error?Boolean (readonly)

Whether the operation failed with a write concern error.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 449

def write_concern_error?
  !!(first_document && first_document['writeConcernError'])
end

Instance Method Details

#cluster_timeClusterTime | nil

Get the cluster time reported in the server response.

Changed in version 2.9.0: This attribute became an instance of ::Mongo::ClusterTime, which is a subclass of BSON::Document. Previously it was an instance of BSON::Document.

Examples:

Get the cluster time.

result.cluster_time

Returns:

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 429

def cluster_time
  first_document && ClusterTime[first_document['$clusterTime']]
end

#cursor_idInteger

Note:

::Mongo::Cursor ids of 0 indicate there is no cursor on the server.

Get the cursor id if the response is acknowledged.

Examples:

Get the cursor id.

result.cursor_id

Returns:

  • (Integer)

    The cursor id.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 176

def cursor_id
  return 0 unless acknowledged?

  if replies.last.respond_to?(:cursor_id)
    # Legacy OP_REPLY replies expose the cursor id directly.
    replies.last.cursor_id
  elsif first_document.key?(CURSOR)
    # OP_MSG command replies carry the cursor id in the `cursor` subdocument.
    first_document[CURSOR][CURSOR_ID] || 0
  else
    0
  end
end

#documentsArray<BSON::Document>

Get the documents in the result.

Examples:

Get the documents.

result.documents

Returns:

  • (Array<BSON::Document>)

    The documents.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 210

def documents
  if acknowledged?
    replies.flat_map(&:documents)
  else
    []
  end
end

#each {|Each| ... } ⇒ Enumerator

Iterate over the documents in the replies.

Examples:

Iterate over the documents.

result.each do |doc|
  p doc
end

Yield Parameters:

  • Each (BSON::Document)

    document in the result.

Returns:

  • (Enumerator)

    The enumerator.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 231

def each(&block)
  documents.each(&block)
end

#errorError::OperationFailure::Family

The exception instance (of Error::OperationFailure::Family) that would be raised during processing of this result.

This method should only be called when result is not successful.

Returns:

  • (Error::OperationFailure::Family)

    The exception.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 345

def error
  @error ||= operation_failure_class.new(
    parser.message,
    self,
    code: parser.code,
    code_name: parser.code_name,
    write_concern_error_document: parser.write_concern_error_document,
    write_concern_error_code: parser.write_concern_error_code,
    write_concern_error_code_name: parser.write_concern_error_code_name,
    write_concern_error_labels: parser.write_concern_error_labels,
    labels: parser.labels,
    wtimeout: parser.wtimeout,
    connection_description: connection_description,
    document: parser.document,
    server_message: parser.server_message,
    server_address: connection_description
  )
end

#first_document (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 473

def first_document
  @first_document ||= first || BSON::Document.new
end

#inspectString

Get the pretty formatted inspection of the result.

Examples:

Inspect the result.

result.inspect

Returns:

  • (String)

    The inspection.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 244

def inspect
  "#<#{self.class.name}:0x#{object_id} documents=#{documents}>"
end

#labelsArray

Gets the set of error labels associated with the result.

Examples:

Get the labels.

result.labels

Returns:

  • (Array)

    labels The set of labels.

Since:

  • 2.7.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 442

def labels
  @labels ||= parser.labels
end

#n

Alias for #written_count.

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 401

alias n written_count

#namespaceNil

Get the namespace of the cursor. The method should be defined in result classes where 'ns' is in the server response.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 197

def namespace
  nil
end

#operation_failure_class (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 461

def operation_failure_class
  if context&.csot? && parser.code == 50
    Error::ServerTimeoutError
  else
    Error::OperationFailure
  end
end

#operation_timeObject | nil

Get the operation time reported in the server response.

Examples:

Get the operation time.

result.operation_time

Returns:

  • (Object | nil)

    The operation time value.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 412

def operation_time
  first_document && first_document[OPERATION_TIME]
end

#parser (private)

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 469

def parser
  @parser ||= Error::Parser.new(first_document, replies)
end

#raise_operation_failure (private)

Raises a Mongo::OperationFailure exception corresponding to the error information in this result.

Raises:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 368

private def raise_operation_failure
  raise error
end

#replyProtocol::Message

Get the reply from the result.

Returns nil if there is no reply (i.e. the operation was an unacknowledged write).

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 257

def reply
  return unless acknowledged?

  replies.first
end

#returned_countInteger

Get the number of documents returned by the server in this batch.

Returns:

  • (Integer)

    The number of documents returned.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 269

def returned_count
  if acknowledged?
    reply.number_returned
  else
    0
  end
end

#snapshot_timestamp

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 453

def snapshot_timestamp
  return unless (doc = reply.documents.first)

  doc['cursor']&.[]('atClusterTime') || doc['atClusterTime']
end

#topology_versionTopologyVersion | nil

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 375

def topology_version
  unless defined?(@topology_version)
    @topology_version = first_document['topologyVersion'] &&
                        TopologyVersion.new(first_document['topologyVersion'])
  end
  @topology_version
end

#validate!Result

Note:

This only checks for errors with writes since authentication is handled at the connection level and any authentication errors would be raised there, before a Result is ever created.

Validate the result by checking for any errors.

Examples:

Validate the result.

result.validate!

Returns:

  • (Result)

    The result if verification passed.

Raises:

  • (Error::OperationFailure::Family)

    If an error is in the result.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 333

def validate!
  successful? ? self : raise_operation_failure
end

#written_countInteger Also known as: #n

Get the number of documents written by the server.

Examples:

Get the number of documents written.

result.written_count

Returns:

  • (Integer)

    The number of documents written.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/operation/result.rb', line 392

def written_count
  if acknowledged?
    first_document[N] || 0
  else
    0
  end
end