/**
* Copyright (C) 2012 10gen 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.
*/
#include "mongo/platform/basic.h"
#include "mongo/s/catalog/mongo_version_range.h"
#include "mongo/util/stringutils.h"
namespace mongo {
using std::string;
using std::vector;
BSONArray MongoVersionRange::toBSONArray(const vector& ranges) {
BSONArrayBuilder barr;
for (vector::const_iterator it = ranges.begin(); it != ranges.end(); ++it) {
const MongoVersionRange& range = *it;
range.toBSONElement(&barr);
}
return barr.arr();
}
bool MongoVersionRange::parseBSONElement(const BSONElement& el, string* errMsg) {
string dummy;
if (!errMsg)
errMsg = &dummy;
if (el.type() == String) {
minVersion = el.String();
if (minVersion == "") {
*errMsg = (string) "cannot parse single empty mongo version (" + el.toString() + ")";
return false;
}
return true;
} else if (el.type() == Array || el.type() == Object) {
BSONObj range = el.Obj();
if (range.nFields() != 2) {
*errMsg = (string) "not enough fields in mongo version range (" + el.toString() + ")";
return false;
}
BSONObjIterator it(range);
BSONElement subElA = it.next();
BSONElement subElB = it.next();
if (subElA.type() != String || subElB.type() != String) {
*errMsg = (string) "wrong field type for mongo version range (" + el.toString() + ")";
return false;
}
minVersion = subElA.String();
maxVersion = subElB.String();
if (minVersion == "") {
*errMsg = (string) "cannot parse first empty mongo version (" + el.toString() + ")";
return false;
}
if (maxVersion == "") {
*errMsg = (string) "cannot parse second empty mongo version (" + el.toString() + ")";
return false;
}
if (versionCmp(minVersion, maxVersion) > 0) {
string swap = minVersion;
minVersion = maxVersion;
maxVersion = swap;
}
return true;
} else {
*errMsg = (string) "wrong type for mongo version range " + el.toString();
return false;
}
}
void MongoVersionRange::toBSONElement(BSONArrayBuilder* barr) const {
if (maxVersion == "") {
barr->append(minVersion);
} else {
BSONArrayBuilder rangeB(barr->subarrayStart());
rangeB.append(minVersion);
rangeB.append(maxVersion);
rangeB.done();
}
}
bool MongoVersionRange::isInRange(StringData version) const {
if (maxVersion == "") {
// If a prefix of the version specified is excluded, the specified version is
// excluded
if (version.find(minVersion) == 0)
return true;
} else {
// Range is inclusive, so make sure the end and beginning prefix excludes all
// prefixed versions as above
if (version.find(minVersion) == 0)
return true;
if (version.find(maxVersion) == 0)
return true;
if (versionCmp(minVersion, version) <= 0 && versionCmp(maxVersion, version) >= 0) {
return true;
}
}
return false;
}
bool isInMongoVersionRanges(StringData version, const vector& ranges) {
for (vector::const_iterator it = ranges.begin(); it != ranges.end(); ++it) {
if (it->isInRange(version))
return true;
}
return false;
}
}