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

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

Constant Summary collapse

CURSOR =

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

The field name for the cursor document in an aggregation.

Since:

  • 2.2.0

'cursor'
CURSOR_ID =

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

The cursor id field in the cursor document.

Since:

  • 2.2.0

'id'
FIRST_BATCH =

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

The field name for the first batch of a cursor.

Since:

  • 2.2.0

'firstBatch'
NEXT_BATCH =

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

The field name for the next batch of a cursor.

Since:

  • 2.2.0

'nextBatch'
NAMESPACE =

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

The namespace field in the cursor document.

Since:

  • 2.2.0

'ns'
N =

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

The number of documents updated in the write.

Since:

  • 2.0.0

'n'
OK =

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

The ok status field in the result.

Since:

  • 2.0.0

'ok'
RESULT =

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

The result field constant.

Since:

  • 2.2.0

'result'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(replies, connection_description = nil, connection_global_id = nil, context: nil, connection: 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.

  • 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) (defaults to: nil)

    the context that was active when this result was produced.

Since:

  • 2.0.0



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 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

#connectionObject (readonly)

Since:

  • 2.0.0



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

def connection
  @connection
end

#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



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

def connection_description
  @connection_description
end

#connection_global_idObject (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 Global is of the connection that the operation was performed on that this result is for.

Returns:

  • (Object)

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

Since:

  • 2.0.0



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

def connection_global_id
  @connection_global_id
end

#contextOperation::Context | nil (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 the operation context (if any) that was active when this result was produced.

Returns:

  • (Operation::Context | nil)

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

Since:

  • 2.0.0



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

def context
  @context
end

#repliesArray<Protocol::Message> (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 replies The wrapped wire protocol replies.

Returns:

Since:

  • 2.0.0



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

def replies
  @replies
end

Instance Method Details

#acknowledged?true, false

Is the result acknowledged?

Returns:

  • (true, false)

    If the result is acknowledged.

Since:

  • 2.0.0



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

def acknowledged?
  !!@replies
end

#cluster_timeClusterTime | nil

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



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

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

#cursor_idInteger

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.

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



185
186
187
# File 'lib/mongo/operation/result.rb', line 185

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



209
210
211
212
213
214
215
# File 'lib/mongo/operation/result.rb', line 209

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



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

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

#errorError::OperationFailure::Family

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 Error::OperationFailure::Family) 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



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/mongo/operation/result.rb', line 344

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
  )
end

#has_cursor_id?true, false

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 result contains cursor_id

Returns:

  • (true, false)

    If the result contains cursor_id.

Since:

  • 2.0.0



170
171
172
# File 'lib/mongo/operation/result.rb', line 170

def has_cursor_id?
  acknowledged? && replies.last.respond_to?(:cursor_id)
end

#inspectString

Get the pretty formatted inspection of the result.

Examples:

Inspect the result.

result.inspect

Returns:

  • (String)

    The inspection.

Since:

  • 2.0.0



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

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

#labelsArray

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.

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



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

def labels
  @labels ||= parser.labels
end

#namespaceNil

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.

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



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

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



308
309
310
311
312
313
314
315
# File 'lib/mongo/operation/result.rb', line 308

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 | 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



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

def operation_time
  first_document && first_document[OPERATION_TIME]
end

#replyProtocol::Message

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.

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



256
257
258
259
260
# File 'lib/mongo/operation/result.rb', line 256

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



268
269
270
271
272
273
274
# File 'lib/mongo/operation/result.rb', line 268

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

#snapshot_timestampObject

Since:

  • 2.0.0



451
452
453
454
455
# File 'lib/mongo/operation/result.rb', line 451

def snapshot_timestamp
  return unless doc = reply.documents.first

  doc['cursor']&.[]('atClusterTime') || doc['atClusterTime']
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



289
290
291
292
293
294
295
296
297
# File 'lib/mongo/operation/result.rb', line 289

def successful?
  return true unless acknowledged?

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

#topology_versionTopologyVersion | nil

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 The topology version.

Returns:

Since:

  • 2.0.0



373
374
375
376
377
378
379
# File 'lib/mongo/operation/result.rb', line 373

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

#validate!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.

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



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

def validate!
  successful? ? self : raise_operation_failure
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



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

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



390
391
392
393
394
395
396
# File 'lib/mongo/operation/result.rb', line 390

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