Class: Mongo::Operation::Result

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/mongo/operation/result.rb,
lib/mongo/operation/shared/result/aggregatable.rb,
lib/mongo/operation/shared/result/use_legacy_error_parser.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

Defined Under Namespace

Modules: Aggregatable, UseLegacyErrorParser

Constant Summary collapse

CURSOR =

The field name for the cursor document in an aggregation.

Since:

  • 2.2.0

'cursor'.freeze
CURSOR_ID =

The cursor id field in the cursor document.

Since:

  • 2.2.0

'id'.freeze
FIRST_BATCH =

The field name for the first batch of a cursor.

Since:

  • 2.2.0

'firstBatch'.freeze
NEXT_BATCH =

The field name for the next batch of a cursor.

Since:

  • 2.2.0

'nextBatch'.freeze
NAMESPACE =

The namespace field in the cursor document.

Since:

  • 2.2.0

'ns'.freeze
N =

The number of documents updated in the write.

Since:

  • 2.0.0

'n'.freeze
OK =

The ok status field in the result.

Since:

  • 2.0.0

'ok'.freeze
RESULT =

The result field constant.

Since:

  • 2.2.0

'result'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(replies, connection_description = nil) ⇒ Result

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize a new result.

For an unkacknowledged write, pass nil in replies.

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

Parameters:

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

    The wire protocol replies.

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

    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.

Since:

  • 2.0.0



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/mongo/operation/result.rb', line 90

def initialize(replies, connection_description = nil)
  if replies
    if replies.is_a?(Array)
      if replies.length != 1
        raise ArgumentError, "Only one (or zero) reply is supported, given #{replies.length}"
      end
      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
  end
end

Instance Attribute Details

#connection_descriptionServer::Description (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Server description of the server that the operation was performed on that this result is for.

Returns:

  • (Server::Description)

    Server description of the server that the operation was performed on that this result is for.

Since:

  • 2.0.0



115
116
117
# File 'lib/mongo/operation/result.rb', line 115

def connection_description
  @connection_description
end

#repliesArray<Protocol::Message> (readonly)

Returns replies The wrapped wire protocol replies.

Returns:

Since:

  • 2.0.0



109
110
111
# File 'lib/mongo/operation/result.rb', line 109

def replies
  @replies
end

Instance Method Details

#acknowledged?true, false

Note:

On MongoDB 2.6 and higher all writes are acknowledged since the driver uses write commands for all write operations. On 2.4 and lower, the result is acknowledged if the GLE has been executed after the command. If not, no replies will be specified. Reads will always return true here since a replies is always provided.

Is the result acknowledged?

Returns:

  • (true, false)

    If the result is acknowledged.

Since:

  • 2.0.0



132
133
134
# File 'lib/mongo/operation/result.rb', line 132

def acknowledged?
  !!@replies
end

#cluster_timenil | ClusterTime

Get the cluster time reported in the server response.

Changed in version 2.9.0: This attribute became an instance of 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



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

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

#cursor_idInteger

Note:

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



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

def cursor_id
  acknowledged? ? replies.last.cursor_id : 0
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



168
169
170
171
172
173
174
# File 'lib/mongo/operation/result.rb', line 168

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



188
189
190
# File 'lib/mongo/operation/result.rb', line 188

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

#errorError::OperationFailure

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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

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

Returns:

Since:

  • 2.0.0



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/mongo/operation/result.rb', line 300

def error
  @error ||= Error::OperationFailure.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,
  )
end

#inspectString

Get the pretty formatted inspection of the result.

Examples:

Inspect the result.

result.inspect

Returns:

  • (String)

    The inspection.

Since:

  • 2.0.0



200
201
202
# File 'lib/mongo/operation/result.rb', line 200

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



387
388
389
# File 'lib/mongo/operation/result.rb', line 387

def labels
  @labels ||= parser.labels
end

#namespaceNil

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

Returns:

  • (Nil)

Since:

  • 2.0.0



156
157
158
# File 'lib/mongo/operation/result.rb', line 156

def namespace
  nil
end

#ok?true, false

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



265
266
267
268
269
270
271
272
# File 'lib/mongo/operation/result.rb', line 265

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

#operation_timeObject

Get the operation time reported in the server response.

Examples:

Get the operation time.

result.operation_time

Returns:

  • (Object)

    The operation time value.

Since:

  • 2.5.0



359
360
361
# File 'lib/mongo/operation/result.rb', line 359

def operation_time
  first_document && first_document[OPERATION_TIME]
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



212
213
214
215
216
217
218
# File 'lib/mongo/operation/result.rb', line 212

def reply
  if acknowledged?
    replies.first
  else
    nil
  end
end

#returned_countInteger

Get the count of documents returned by the server.

Examples:

Get the number returned.

result.returned_count

Returns:

  • (Integer)

    The number of documents returned.

Since:

  • 2.0.0



228
229
230
231
232
233
234
# File 'lib/mongo/operation/result.rb', line 228

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

#successful?true, false

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



248
249
250
251
252
253
254
255
# File 'lib/mongo/operation/result.rb', line 248

def successful?
  return true if !acknowledged?
  if first_document.has_key?(OK)
    ok? && parser.message.empty?
  else
    !query_failure? && parser.message.empty?
  end
end

#topology_versionTopologyVersion | nil

Returns The topology version.

Returns:

Since:

  • 2.0.0



326
327
328
329
330
331
332
# File 'lib/mongo/operation/result.rb', line 326

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:

Since:

  • 2.0.0



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

def validate!
  !successful? ? raise_operation_failure : self
end

#write_concern_error?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether the operation failed with a write concern error.

Returns:

  • (Boolean)

Since:

  • 2.0.0



394
395
396
# File 'lib/mongo/operation/result.rb', line 394

def write_concern_error?
  !!(first_document && first_document['writeConcernError'])
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



342
343
344
345
346
347
348
# File 'lib/mongo/operation/result.rb', line 342

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