Пример #1
0
TEST_F(UpdateArrayNodeTest, UpdateIsAppliedToAllMatchingElements) {
    auto update = fromjson("{$set: {'a.$[i]': 2}}");
    auto arrayFilter = fromjson("{i: 0}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
    auto parsedFilter = assertGet(MatchExpressionParser::parse(arrayFilter, expCtx));
    arrayFilters["i"] = assertGet(ExpressionWithPlaceholder::make(std::move(parsedFilter)));
    std::set<std::string> foundIdentifiers;
    UpdateObjectNode root;
    ASSERT_OK(UpdateObjectNode::parseAndMerge(&root,
                                              modifiertable::ModifierType::MOD_SET,
                                              update["$set"]["a.$[i]"],
                                              expCtx,
                                              arrayFilters,
                                              foundIdentifiers));

    mutablebson::Document doc(fromjson("{a: [0, 1, 0]}"));
    addIndexedPath("a");
    auto result = root.apply(getApplyParams(doc.root()));
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_FALSE(result.noop);
    ASSERT_EQUALS(fromjson("{a: [2, 1, 2]}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$set: {a: [2, 1, 2]}}"), getLogDoc());
    ASSERT_EQUALS("{a.0, a.2}", getModifiedPaths());
}
Пример #2
0
void
PathGroups::addPath(QString flnm)
{
  QFile fpath(flnm);
  fpath.open(QFile::ReadOnly);
  QTextStream fd(&fpath);

  QString line = fd.readLine();
  if (line.contains("#indexed", Qt::CaseInsensitive))
    {
      addIndexedPath(flnm);
      return;
    }


  PathGroupGrabber *pg = new PathGroupGrabber();

  while (! fd.atEnd())
    {
      QStringList list = line.split(" ", QString::SkipEmptyParts);
      if (list.count() == 1)
	{
	  int npts = list[0].toInt();
	  QList<Vec> pts;
	  for(int i=0; i<npts; i++)
	    {
	      if (fd.atEnd())
		break;
	      else
		{
		  QString line = fd.readLine();
		  QStringList list = line.split(" ", QString::SkipEmptyParts);
		  if (list.count() == 3)
		    {
		      float x = list[0].toFloat();
		      float y = list[1].toFloat();
		      float z = list[2].toFloat();
		      pts.append(Vec(x,y,z));
		    }
		}
	    }

	  if (pts.count() > 0)
	    pg->addPoints(pts);		  
	}
      line = fd.readLine();
    }

  m_paths.append(pg);
  
  makePathConnections();
}
Пример #3
0
TEST_F(PopNodeTest, NoopWhenFirstPathComponentDoesNotExist) {
    auto update = fromjson("{$pop: {'a.b': 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    PopNode popNode;
    ASSERT_OK(popNode.init(update["$pop"]["a.b"], expCtx));

    mmb::Document doc(fromjson("{b: [1, 2, 3]}"));
    setPathToCreate("a.b");
    addIndexedPath("a.b");
    auto result = popNode.apply(getApplyParams(doc.root()));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{b: [1, 2, 3]}"), doc);
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
}
Пример #4
0
TEST_F(PopNodeTest, NoopWhenNumericalPathComponentExceedsArrayLength) {
    auto update = fromjson("{$pop: {'a.0': 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    PopNode popNode;
    ASSERT_OK(popNode.init(update["$pop"]["a.0"], expCtx));

    mmb::Document doc(fromjson("{a: []}"));
    setPathToCreate("0");
    setPathTaken("a");
    addIndexedPath("a.0");
    auto result = popNode.apply(getApplyParams(doc.root()["a"]));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: []}"), doc);
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
}
Пример #5
0
TEST_F(UnsetNodeTest, ApplyFieldWithDot) {
    auto update = fromjson("{$unset: {'a.b': 1}}");
    const CollatorInterface* collator = nullptr;
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a.b"], collator));

    mutablebson::Document doc(fromjson("{'a.b':4, a: {b: 2}}"));
    setPathTaken("a.b");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{'a.b':4, a: {}}"), doc);
    ASSERT_FALSE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$unset: {'a.b': true}}"), getLogDoc());
}
Пример #6
0
TEST_F(UnsetNodeTest, UnsetNoOpEmptyDoc) {
    auto update = fromjson("{$unset: {a: 1}}");
    const CollatorInterface* collator = nullptr;
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a"], collator));

    mutablebson::Document doc(fromjson("{}"));
    setPathToCreate("a");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
}
Пример #7
0
TEST_F(PopNodeTest, NoopWhenPathPartiallyExists) {
    auto update = fromjson("{$pop: {'a.b.c': 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    PopNode popNode;
    ASSERT_OK(popNode.init(update["$pop"]["a.b.c"], expCtx));

    mmb::Document doc(fromjson("{a: {}}"));
    setPathToCreate("b.c");
    setPathTaken("a");
    addIndexedPath("a.b.c");
    auto result = popNode.apply(getApplyParams(doc.root()["a"]));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: {}}"), doc);
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
}
Пример #8
0
TEST_F(PopNodeTest, ThrowsWhenPathIsBlockedByAScalar) {
    auto update = fromjson("{$pop: {'a.b': 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    PopNode popNode;
    ASSERT_OK(popNode.init(update["$pop"]["a.b"], expCtx));

    mmb::Document doc(fromjson("{a: 'foo'}"));
    setPathToCreate("b");
    setPathTaken("a");
    addIndexedPath("a.b");
    ASSERT_THROWS_CODE_AND_WHAT(
        popNode.apply(getApplyParams(doc.root()["a"])),
        AssertionException,
        ErrorCodes::PathNotViable,
        "Cannot use the part (b) of (a.b) to traverse the element ({a: \"foo\"})");
}
Пример #9
0
TEST_F(CompareNodeTest, ApplyMaxNumberIsLess) {
    auto update = fromjson("{$max: {a: 0}}");
    const CollatorInterface* collator = nullptr;
    CompareNode node(CompareNode::CompareMode::kMax);
    ASSERT_OK(node.init(update["$max"]["a"], collator));

    mutablebson::Document doc(fromjson("{a: 1}"));
    setPathTaken("a");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: 1}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
}
Пример #10
0
TEST_F(CompareNodeTest, ApplyMinRespectsCollation) {
    auto update = fromjson("{$min: {a: 'dba'}}");
    const CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
    CompareNode node(CompareNode::CompareMode::kMin);
    ASSERT_OK(node.init(update["$min"]["a"], &collator));

    mutablebson::Document doc(fromjson("{a: 'cbc'}"));
    setPathTaken("a");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: 'dba'}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$set: {a: 'dba'}}"), getLogDoc());
}
Пример #11
0
TEST_F(CompareNodeTest, ApplyMinSameValIntZero) {
    auto update = BSON("$min" << BSON("a" << 0LL));
    const CollatorInterface* collator = nullptr;
    CompareNode node(CompareNode::CompareMode::kMin);
    ASSERT_OK(node.init(update["$min"]["a"], collator));

    mutablebson::Document doc(fromjson("{a: 0.0}"));
    setPathTaken("a");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: 0.0}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
}
Пример #12
0
TEST_F(UnsetNodeTest, UnsetPositional) {
    auto update = fromjson("{$unset: {'a.$': 1}}");
    const CollatorInterface* collator = nullptr;
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a.$"], collator));

    mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
    setPathTaken("a.1");
    setMatchedField("1");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]["1"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: [0, null, 2]}"), doc);
    ASSERT_FALSE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$unset: {'a.1': true}}"), getLogDoc());
}
TEST_F(UnsetNodeTest, ApplyFieldWithDot) {
    auto update = fromjson("{$unset: {'a.b': 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a.b"], expCtx));

    mutablebson::Document doc(fromjson("{'a.b':4, a: {b: 2}}"));
    setPathTaken("a.b");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]["b"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{'a.b':4, a: {}}"), doc);
    ASSERT_FALSE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$unset: {'a.b': true}}"), getLogDoc());
    ASSERT_EQUALS(getModifiedPaths(), "{a.b}");
}
TEST_F(UnsetNodeTest, UnsetNoOpEmptyDoc) {
    auto update = fromjson("{$unset: {a: 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a"], expCtx));

    mutablebson::Document doc(fromjson("{}"));
    setPathToCreate("a");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()));
    ASSERT_TRUE(result.noop);
    ASSERT_FALSE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{}"), getLogDoc());
    ASSERT_EQUALS(getModifiedPaths(), "{a}");
}
TEST_F(UnsetNodeTest, UnsetPositional) {
    auto update = fromjson("{$unset: {'a.$': 1}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a.$"], expCtx));

    mutablebson::Document doc(fromjson("{a: [0, 1, 2]}"));
    setPathTaken("a.1");
    setMatchedField("1");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"][1]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: [0, null, 2]}"), doc);
    ASSERT_FALSE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$unset: {'a.1': true}}"), getLogDoc());
    ASSERT_EQUALS(getModifiedPaths(), "{a.1}");
}
Пример #16
0
TEST_F(UnsetNodeTest, ApplyCanRemoveRequiredPartOfDBRefIfValidateForStorageIsFalse) {
    auto update = fromjson("{$unset: {'a.$id': true}}");
    const CollatorInterface* collator = nullptr;
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a.$id"], collator));

    mutablebson::Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
    setPathTaken("a.$id");
    addIndexedPath("a");
    setValidateForStorage(false);
    auto result = node.apply(getApplyParams(doc.root()["a"]["$id"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    auto updated = BSON("a" << BSON("$ref"
                                    << "c"));
    ASSERT_EQUALS(updated, doc);
    ASSERT_FALSE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$unset: {'a.$id': true}}"), getLogDoc());
}
TEST_F(UnsetNodeTest, ApplyCanRemoveRequiredPartOfDBRefIfValidateForStorageIsFalse) {
    auto update = fromjson("{$unset: {'a.$id': true}}");
    boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    UnsetNode node;
    ASSERT_OK(node.init(update["$unset"]["a.$id"], expCtx));

    mutablebson::Document doc(fromjson("{a: {$ref: 'c', $id: 0}}"));
    setPathTaken("a.$id");
    addIndexedPath("a");
    setValidateForStorage(false);
    auto result = node.apply(getApplyParams(doc.root()["a"]["$id"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    auto updated = BSON("a" << BSON("$ref"
                                    << "c"));
    ASSERT_EQUALS(updated, doc);
    ASSERT_FALSE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$unset: {'a.$id': true}}"), getLogDoc());
    ASSERT_EQUALS(getModifiedPaths(), "{a.$id}");
}
Пример #18
0
TEST_F(CompareNodeTest, ApplyMaxRespectsCollationFromSetCollator) {
    auto update = fromjson("{$max: {a: 'abd'}}");
    const CollatorInterface* binaryComparisonCollator = nullptr;
    CompareNode node(CompareNode::CompareMode::kMax);
    ASSERT_OK(node.init(update["$max"]["a"], binaryComparisonCollator));

    const CollatorInterfaceMock reverseStringCollator(
        CollatorInterfaceMock::MockType::kReverseString);
    node.setCollator(&reverseStringCollator);

    mutablebson::Document doc(fromjson("{a: 'cbc'}"));
    setPathTaken("a");
    addIndexedPath("a");
    auto result = node.apply(getApplyParams(doc.root()["a"]));
    ASSERT_FALSE(result.noop);
    ASSERT_TRUE(result.indexesAffected);
    ASSERT_EQUALS(fromjson("{a: 'abd'}"), doc);
    ASSERT_TRUE(doc.isInPlaceModeEnabled());
    ASSERT_EQUALS(fromjson("{$set: {a: 'abd'}}"), getLogDoc());
}