...

Source file src/go.mongodb.org/mongo-driver/mongo/integration/unified/result.go

Documentation: go.mongodb.org/mongo-driver/mongo/integration/unified

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package unified
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  
    13  	"go.mongodb.org/mongo-driver/bson"
    14  	"go.mongodb.org/mongo-driver/bson/bsontype"
    15  )
    16  
    17  // operationResult holds the result and/or error returned by an op.
    18  type operationResult struct {
    19  	// For operations that return a single result, this field holds a BSON representation.
    20  	Result bson.RawValue
    21  
    22  	// CursorResult holds the documents retrieved by iterating a Cursor.
    23  	CursorResult []bson.Raw
    24  
    25  	// Err holds the error returned by an operation. This is mutually exclusive with CursorResult but not with Result
    26  	// because some operations (e.g. bulkWrite) can return both a result and an error.
    27  	Err error
    28  }
    29  
    30  // newEmptyResult returns an operationResult with no fields set. This should be used if the operation does not check
    31  // results or errors.
    32  func newEmptyResult() *operationResult {
    33  	return &operationResult{}
    34  }
    35  
    36  // newDocumentResult is a helper to create a value result where the value is a BSON document.
    37  func newDocumentResult(result []byte, err error) *operationResult {
    38  	return newValueResult(bsontype.EmbeddedDocument, result, err)
    39  }
    40  
    41  // newValueResult creates an operationResult where the result is a BSON value of an arbitrary type. Because some
    42  // operations can return both a result and an error (e.g. bulkWrite), the err parameter should be the error returned
    43  // by the op, if any.
    44  func newValueResult(valueType bsontype.Type, data []byte, err error) *operationResult {
    45  	return &operationResult{
    46  		Result: bson.RawValue{Type: valueType, Value: data},
    47  		Err:    err,
    48  	}
    49  }
    50  
    51  // newCursorResult creates an operationResult that contains documents retrieved by fully iterating a cursor.
    52  func newCursorResult(arr []bson.Raw) *operationResult {
    53  	// If the operation returned no documents, the array might be nil. It isn't possible to distinguish between this
    54  	// case and the case where there is no cursor result, so we overwrite the result with an non-nil empty slice.
    55  	result := arr
    56  	if result == nil {
    57  		result = make([]bson.Raw, 0)
    58  	}
    59  
    60  	return &operationResult{
    61  		CursorResult: result,
    62  	}
    63  }
    64  
    65  // newErrorResult creates an operationResult that only holds an error. This should only be used when executing an
    66  // operation that can return a result or an error, but not both.
    67  func newErrorResult(err error) *operationResult {
    68  	return &operationResult{
    69  		Err: err,
    70  	}
    71  }
    72  
    73  // verifyOperationResult checks that the actual and expected results match
    74  func verifyOperationResult(ctx context.Context, expected bson.RawValue, actual *operationResult) error {
    75  	actualVal := actual.Result
    76  	if actual.CursorResult != nil {
    77  		_, data, err := bson.MarshalValue(actual.CursorResult)
    78  		if err != nil {
    79  			return fmt.Errorf("error converting cursorResult array to BSON: %v", err)
    80  		}
    81  
    82  		actualVal = bson.RawValue{
    83  			Type:  bsontype.Array,
    84  			Value: data,
    85  		}
    86  	}
    87  
    88  	// For document results and arrays of root documents (i.e. cursor results), the actual value can have additional
    89  	// top-level keys. Single-value array results (e.g. from distinct) must match exactly, so we set extraKeysAllowed to
    90  	// false only for that case.
    91  	extraKeysAllowed := actual.Result.Type != bsontype.Array
    92  	return verifyValuesMatch(ctx, expected, actualVal, extraKeysAllowed)
    93  }
    94  

View as plain text