hydrate-mongodb
Version:
An Object Document Mapper (ODM) for MongoDB.
166 lines (165 loc) • 8.28 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var mappingModel_1 = require("../mapping/mappingModel");
var criteriaBuilder_1 = require("./criteriaBuilder");
var persistenceError_1 = require("../persistenceError");
var UpdateDocumentBuilder = (function (_super) {
__extends(UpdateDocumentBuilder, _super);
function UpdateDocumentBuilder() {
return _super !== null && _super.apply(this, arguments) || this;
}
UpdateDocumentBuilder.prototype.build = function (updateDocument) {
this.error = undefined;
if (!updateDocument)
return {};
var result = {};
for (var operator in updateDocument) {
if (updateDocument.hasOwnProperty(operator)) {
if (operator[0] != "$") {
this.error = new persistenceError_1.PersistenceError("Replacement documents are not support in updates. Use the Session's 'save' method.");
return null;
}
var fields = updateDocument[operator];
if (!fields) {
this.error = new persistenceError_1.PersistenceError("Missing value for operator '" + operator + "'.");
return null;
}
var preparedFields = {};
if (operator == '$pull') {
preparedFields = this.prepareQueryDocument(fields, this.mapping);
}
else {
for (var field in fields) {
if (fields.hasOwnProperty(field)) {
var context = this.mapping.resolve(field);
if (context.error) {
this.error = context.error;
return null;
}
var mapping = context.resolvedMapping, value = fields[field], preparedValue;
switch (operator) {
case '$currentDate':
case '$inc':
case '$mul':
case '$rename':
case '$unset':
case '$pop':
case '$bit':
preparedValue = value;
break;
case '$addToSet':
case '$push':
if (!this._isArray(operator, mapping))
return null;
if (this.isQueryExpression(value)) {
preparedValue = this._prepareQueryModifier(operator, value, mapping.elementMapping);
break;
}
preparedValue = this.prepareQueryValue(operator, value, mapping.elementMapping);
break;
case '$max':
case '$min':
case '$setOnInsert':
case '$set':
preparedValue = this.prepareQueryValue(operator, value, mapping);
break;
case '$pullAll':
case '$pushAll':
if (!this._isArray(operator, mapping))
return null;
preparedValue = this.prepareArrayOfValues(operator, value, mapping.elementMapping);
break;
default:
this.error = new persistenceError_1.PersistenceError("Unknown query operator '" + operator + "'.");
return null;
}
preparedFields[context.resolvedPath] = preparedValue;
}
}
}
result[operator] = preparedFields;
}
}
return result;
};
UpdateDocumentBuilder.prototype._isArray = function (operator, mapping) {
if (!(mapping.flags & 1)) {
this.error = new persistenceError_1.PersistenceError("Operator '" + operator + "' only applies to properties that have an array type.");
return false;
}
return true;
};
UpdateDocumentBuilder.prototype._prepareQueryModifier = function (operator, query, mapping) {
if (!query) {
this.error = new persistenceError_1.PersistenceError("Missing value for operator '" + operator + "'.");
return null;
}
var result = {};
for (var key in query) {
if (query.hasOwnProperty(key)) {
if (key[0] != "$") {
this.error = new persistenceError_1.PersistenceError("Unexpected value '" + key + "' in query expression.");
return null;
}
var value = query[key], preparedValue;
switch (key) {
case '$each':
preparedValue = this.prepareArrayOfValues(key, value, mapping);
break;
case '$position':
case '$slice':
preparedValue = value;
break;
case '$sort':
preparedValue = this._prepareSortSpecification(value, mapping);
break;
default:
this.error = new persistenceError_1.PersistenceError("Unknown query modifier '" + key + "'.");
return null;
}
result[key] = preparedValue;
}
}
return result;
};
UpdateDocumentBuilder.prototype._prepareSortSpecification = function (sortSpecification, mapping) {
if (mapping.flags & 2048) {
if (typeof sortSpecification !== "object") {
this.error = new persistenceError_1.PersistenceError("Value of $sort must be an object if sorting an array of embedded documents.");
}
var result = {};
for (var field in sortSpecification) {
if (sortSpecification.hasOwnProperty(field)) {
var property = mapping.getProperty(field);
if (property === undefined) {
if (mapping.flags & 4) {
this.error = new persistenceError_1.PersistenceError("Unknown property '" + field + "' for class '" + mapping.name + "' in $sort.");
}
else {
this.error = new persistenceError_1.PersistenceError("Unknown property '" + field + "' in $sort.");
}
return;
}
property.setFieldValue(result, this.prepareQueryValue(property.name, property.getPropertyValue(sortSpecification), property.mapping));
}
}
return result;
}
if (typeof sortSpecification !== "number") {
this.error = new persistenceError_1.PersistenceError("Value of $sort must be a number if sorting an array that does not contain embedded documents.");
}
return sortSpecification;
};
return UpdateDocumentBuilder;
}(criteriaBuilder_1.CriteriaBuilder));
exports.UpdateDocumentBuilder = UpdateDocumentBuilder;