summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/create_collection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/create_collection.cpp')
-rw-r--r--src/mongo/db/catalog/create_collection.cpp159
1 files changed, 39 insertions, 120 deletions
diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
index c64decf02a3..74be2bd73e4 100644
--- a/src/mongo/db/catalog/create_collection.cpp
+++ b/src/mongo/db/catalog/create_collection.cpp
@@ -44,7 +44,7 @@
#include "mongo/db/catalog/index_key_validate.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/create_gen.h"
-#include "mongo/db/concurrency/exception_util.h"
+#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/index/index_descriptor.h"
@@ -117,9 +117,7 @@ Status validateClusteredIndexSpec(OperationContext* opCtx,
if (expireAfterSeconds) {
// Not included in the indexSpec itself.
- auto status = index_key_validate::validateExpireAfterSeconds(
- *expireAfterSeconds,
- index_key_validate::ValidateExpireAfterSecondsMode::kClusteredTTLIndex);
+ auto status = index_key_validate::validateExpireAfterSeconds(*expireAfterSeconds);
if (!status.isOK()) {
return status;
}
@@ -208,117 +206,6 @@ Status _createView(OperationContext* opCtx,
});
}
-BSONObj _generateTimeseriesValidator(StringData timeField) {
- // '$jsonSchema' : {
- // bsonType: 'object',
- // required: ['_id', 'control', 'data'],
- // properties: {
- // _id: {bsonType: 'objectId'},
- // control: {
- // bsonType: 'object',
- // required: ['version', 'min', 'max'],
- // properties: {
- // version: {bsonType: 'number'},
- // min: {
- // bsonType: 'object',
- // required: ['%s'],
- // properties: {'%s': {bsonType: 'date'}}
- // },
- // max: {
- // bsonType: 'object',
- // required: ['%s'],
- // properties: {'%s': {bsonType: 'date'}}
- // },
- // closed: {bsonType: 'bool'},
- // count: {bsonType: 'number', minimum: 1},
- // },
- // additionalProperties: false,
- // },
- // data: {bsonType: 'object'},
- // meta: {}
- // },
- // additionalProperties: false
- // }
- BSONObjBuilder validator;
- BSONObjBuilder schema(validator.subobjStart("$jsonSchema"));
- schema.append("bsonType", "object");
- schema.append("required",
- BSON_ARRAY("_id"
- << "control"
- << "data"));
- {
- BSONObjBuilder properties(schema.subobjStart("properties"));
- {
- BSONObjBuilder _id(properties.subobjStart("_id"));
- _id.append("bsonType", "objectId");
- _id.done();
- }
- {
- BSONObjBuilder control(properties.subobjStart("control"));
- control.append("bsonType", "object");
- control.append("required",
- BSON_ARRAY("version"
- << "min"
- << "max"));
- {
- BSONObjBuilder innerProperties(control.subobjStart("properties"));
- {
- BSONObjBuilder version(innerProperties.subobjStart("version"));
- version.append("bsonType", "number");
- version.done();
- }
- {
- BSONObjBuilder min(innerProperties.subobjStart("min"));
- min.append("bsonType", "object");
- min.append("required", BSON_ARRAY(timeField));
- BSONObjBuilder minProperties(min.subobjStart("properties"));
- BSONObjBuilder timeFieldObj(minProperties.subobjStart(timeField));
- timeFieldObj.append("bsonType", "date");
- timeFieldObj.done();
- minProperties.done();
- min.done();
- }
-
- {
- BSONObjBuilder max(innerProperties.subobjStart("max"));
- max.append("bsonType", "object");
- max.append("required", BSON_ARRAY(timeField));
- BSONObjBuilder maxProperties(max.subobjStart("properties"));
- BSONObjBuilder timeFieldObj(maxProperties.subobjStart(timeField));
- timeFieldObj.append("bsonType", "date");
- timeFieldObj.done();
- maxProperties.done();
- max.done();
- }
- {
- BSONObjBuilder closed(innerProperties.subobjStart("closed"));
- closed.append("bsonType", "bool");
- closed.done();
- }
- {
- BSONObjBuilder count(innerProperties.subobjStart("count"));
- count.append("bsonType", "number");
- count.append("minimum", 1);
- count.done();
- }
- innerProperties.done();
- }
- control.append("additionalProperties", false);
- control.done();
- }
- {
- BSONObjBuilder data(properties.subobjStart("data"));
- data.append("bsonType", "object");
- data.done();
- }
- properties.append("meta", BSONObj{});
- properties.done();
- }
- schema.append("additionalProperties", false);
- schema.done();
- return validator.obj();
-}
-
Status _createTimeseries(OperationContext* opCtx,
const NamespaceString& ns,
const CollectionOptions& optionsArg) {
@@ -343,13 +230,46 @@ Status _createTimeseries(OperationContext* opCtx,
maxSpanSeconds == options.timeseries->getBucketMaxSpanSeconds());
options.timeseries->setBucketMaxSpanSeconds(maxSpanSeconds);
-
// Set the validator option to a JSON schema enforcing constraints on bucket documents.
// This validation is only structural to prevent accidental corruption by users and
// cannot cover all constraints. Leave the validationLevel and validationAction to their
// strict/error defaults.
auto timeField = options.timeseries->getTimeField();
- auto validatorObj = _generateTimeseriesValidator(timeField);
+ auto validatorObj = fromjson(fmt::sprintf(R"(
+{
+'$jsonSchema' : {
+ bsonType: 'object',
+ required: ['_id', 'control', 'data'],
+ properties: {
+ _id: {bsonType: 'objectId'},
+ control: {
+ bsonType: 'object',
+ required: ['version', 'min', 'max'],
+ properties: {
+ version: {bsonType: 'number'},
+ min: {
+ bsonType: 'object',
+ required: ['%s'],
+ properties: {'%s': {bsonType: 'date'}}
+ },
+ max: {
+ bsonType: 'object',
+ required: ['%s'],
+ properties: {'%s': {bsonType: 'date'}}
+ },
+ closed: {bsonType: 'bool'}
+ }
+ },
+ data: {bsonType: 'object'},
+ meta: {}
+ },
+ additionalProperties: false
+}
+})",
+ timeField,
+ timeField,
+ timeField,
+ timeField));
bool existingBucketCollectionIsCompatible = false;
@@ -401,9 +321,8 @@ Status _createTimeseries(OperationContext* opCtx,
// Cluster time-series buckets collections by _id.
auto expireAfterSeconds = options.expireAfterSeconds;
if (expireAfterSeconds) {
- uassertStatusOK(index_key_validate::validateExpireAfterSeconds(
- *expireAfterSeconds,
- index_key_validate::ValidateExpireAfterSecondsMode::kClusteredTTLIndex));
+ uassertStatusOK(
+ index_key_validate::validateExpireAfterSeconds(*expireAfterSeconds));
bucketsOptions.expireAfterSeconds = expireAfterSeconds;
}