/**
* Copyright (C) 2016 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects for
* all of the code used other than as permitted herein. If you modify file(s)
* with this exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
#pragma once
#include
#include
#include "mongo/bson/bsonelement_comparator_interface.h"
#include "mongo/bson/bsonobj.h"
namespace mongo {
namespace dotted_path_support {
/**
* Returns the element at the specified path. This function returns BSONElement() if the element
* wasn't found.
*
* The 'path' can be specified using a dotted notation in order to traverse through embedded objects
* and array elements.
*
* Some examples:
*
* Consider the document {a: {b: 1}} and the path "a.b". An element with key="b" and value=1 would
* be returned.
*
* Consider the document {a: [{b: 1}]} and the path "a.b". BSONElement() would be returned because
* the array value is actually an object with key="0" and value={b: 1}.
*
* Consider the document {a: [{b: 1}]} and the path "a.0.b". An element with key="b" and value=1
* would be returned.
*/
BSONElement extractElementAtPath(const BSONObj& obj, StringData path);
/**
* Returns the element at the specified path, or the first element with an array value encountered
* along the specified path. This function returns BSONElement() if the element wasn't found.
*
* The 'path' can be specified using a dotted notation in order to traverse through embedded objects
* and array elements.
*
* This function modifies 'path' to be the suffix of the path that follows the first element with an
* array value. If no such element is present, then 'path' is set as the empty string.
*
* Some examples:
*
* Consider the document {a: {b: [1]}} and the path "a.b". An element with key="b" and value=1
* would be returned. 'path' would be changed to the empty string.
*
* Consider the document {a: [{b: 1}]} and the path "a.b". An element with key="a" and
* value=[{b: 1}] would be returned. 'path' would be changed to the string "b".
*/
BSONElement extractElementAtPathOrArrayAlongPath(const BSONObj& obj, const char*& path);
/**
* Expands arrays along the specified path and adds all elements to the 'elements' set.
*
* The 'path' can be specified using a dotted notation in order to traverse through embedded objects
* and array elements.
*
* This function fills 'arrayComponents' with the positions (starting at 0) of 'path' corresponding
* to array values.
*
* Some examples:
*
* Consider the document {a: [{b: 1}, {b: 2}]} and the path "a.b". The elements {b: 1} and {b: 2}
* would be added to the set. 'arrayComponents' would be set as std::set{0U}.
*
* Consider the document {a: [{b: [1, 2]}, {b: [2, 3]}]} and the path "a.b". The elements {b: 1},
* {b: 2}, and {b: 3} would be added to the set and 'arrayComponents' would be set as
* std::set{0U, 1U} if 'expandArrayOnTrailingField' is true. The elements {b: [1, 2]} and
* {b: [2, 3]} would be added to the set and 'arrayComponents' would be set as
* std::set{0U} if 'expandArrayOnTrailingField' is false.
*/
void extractAllElementsAlongPath(const BSONObj& obj,
StringData path,
BSONElementSet& elements,
bool expandArrayOnTrailingField = true,
std::set* arrayComponents = nullptr);
void extractAllElementsAlongPath(const BSONObj& obj,
StringData path,
BSONElementMultiSet& elements,
bool expandArrayOnTrailingField = true,
std::set* arrayComponents = nullptr);
/**
* Returns an owned BSONObj with elements in the same order as they appear in the 'pattern' object
* and values extracted from 'obj'.
*
* The keys of the elements in the 'pattern' object can be specified using a dotted notation in
* order to traverse through embedded objects and array elements. The values of the elements in the
* 'pattern' object are ignored.
*
* If 'useNullIfMissing' is true and the key in the 'pattern' object isn't present in 'obj', then a
* null value is appended to the returned value instead.
*
* Some examples:
*
* Consider the document {a: 1, b: 1} and the template {b: ""}. The object {b: 1} would be
* returned.
*
* Consider the document {a: {b: 1}} and the template {"a.b": ""}. The object {"a.b": 1} would be
* returned.
*
* Consider the document {b: 1} and the template {a: "", b: ""}. The object {a: null, b: 1} would
* be returned if 'useNullIfMissing' is true. The object {b: 1} would be returned if
* 'useNullIfMissing' is false.
*/
BSONObj extractElementsBasedOnTemplate(const BSONObj& obj,
const BSONObj& pattern,
bool useNullIfMissing = false);
/**
* Compares two objects according to order of elements in the 'sortKey' object. This function
* returns -1 if 'firstObj' < 'secondObj' according to 'sortKey', 0 if 'firstObj' == 'secondObj'
* according to 'sortKey', and 1 if 'firstObj' > 'secondObj' according to 'sortKey'.
*
* If 'assumeDottedPaths' is true, then extractElementAtPath() is used to get the element associated
* with the key of an element in the 'sortKey' object. If 'assumeDottedPaths' is false, then
* BSONObj::getField() is used to get the element associated with the key of an element in the
* 'sortKey' object. BSONObj::getField() searches the object for the key verbatim and does no
* special handling to traverse through embedded objects and array elements when a "." character is
* specified.
*
* Unlike with BSONObj::woCompare(), the elements don't need to be in the same order between
* 'firstObj' and 'secondObj'.
*/
int compareObjectsAccordingToSort(const BSONObj& firstObj,
const BSONObj& secondObj,
const BSONObj& sortKey,
bool assumeDottedPaths = false);
} // namespace dotted_path_support
} // namespace mongo