hydrate-mongodb
Version:
An Object Document Mapper (ODM) for MongoDB.
234 lines (233 loc) • 9.91 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 objectMapping_1 = require("./objectMapping");
var mappingRegistry_1 = require("./mappingRegistry");
var mappingModel_1 = require("./mappingModel");
var persistenceError_1 = require("../persistenceError");
var OriginalDocument = Symbol();
var ClassMapping = (function (_super) {
__extends(ClassMapping, _super);
function ClassMapping(baseClass) {
var _this = _super.call(this) || this;
_this.flags |= 4;
_this._baseClass = baseClass;
if (!baseClass) {
_this.flags |= 4096;
_this.inheritanceRoot = _this;
}
else {
var previous = baseClass;
while (baseClass) {
baseClass._addSubClass(_this);
previous = baseClass;
baseClass = baseClass._baseClass;
}
_this.inheritanceRoot = previous;
}
return _this;
}
Object.defineProperty(ClassMapping.prototype, "discriminatorValue", {
get: function () {
return this._discriminatorValue;
},
enumerable: true,
configurable: true
});
ClassMapping.prototype.setDiscriminatorValue = function (value) {
if (typeof value !== "string") {
throw new persistenceError_1.PersistenceError("Expected string for discriminator value.");
}
this._discriminatorValue = value;
this._addDiscriminatorMapping(value, this);
};
ClassMapping.prototype.setQueryDocumentDiscriminator = function (obj) {
var discriminators;
if ((this.flags & 4096) == 0) {
discriminators = [];
this._getDescendantDiscriminators(discriminators);
}
if (!discriminators || discriminators.length == 0) {
this.setQueryDocumentDiscriminator = (function () { });
return;
}
var discriminator;
if (discriminators.length == 1) {
discriminator = discriminators[0];
}
else {
discriminator = {
'$in': discriminators
};
}
obj[this.inheritanceRoot.discriminatorField] = discriminator;
this.setQueryDocumentDiscriminator = (new Function("o", "o['" + this.inheritanceRoot.discriminatorField + "'] = " + JSON.stringify(discriminator)));
};
ClassMapping.prototype.setDocumentDiscriminator = function (obj) {
if (this._discriminatorValue === undefined) {
this.setDocumentDiscriminator = (function () { });
return;
}
this.setDocumentDiscriminator = (new Function("o", "o['" + this.inheritanceRoot.discriminatorField + "'] = \"" + this._discriminatorValue + "\""));
obj[this.inheritanceRoot.discriminatorField] = this._discriminatorValue;
};
ClassMapping.prototype.getDocumentDiscriminator = function (obj) {
this.getDocumentDiscriminator = (new Function("o", "return o['" + this.inheritanceRoot.discriminatorField + "']"));
return obj[this.inheritanceRoot.discriminatorField];
};
ClassMapping.prototype._getDescendantDiscriminators = function (discriminators) {
if (this._discriminatorValue) {
discriminators.push(this._discriminatorValue);
}
var subclasses = this._subclasses;
if (subclasses) {
for (var i = 0; i < subclasses.length; i++) {
var discriminatorValue = subclasses[i]._discriminatorValue;
if (discriminatorValue) {
discriminators.push(discriminatorValue);
}
}
}
};
Object.defineProperty(ClassMapping.prototype, "hasSubClasses", {
get: function () {
return this._subclasses && this._subclasses.length > 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ClassMapping.prototype, "hasBaseClass", {
get: function () {
return this._baseClass !== undefined;
},
enumerable: true,
configurable: true
});
ClassMapping.prototype._addSubClass = function (subclass) {
if (!this._subclasses) {
this._subclasses = [];
}
this._subclasses.push(subclass);
};
ClassMapping.prototype._addDiscriminatorMapping = function (value, mapping) {
if (!this._discriminatorMap) {
this._discriminatorMap = new Map();
}
if (this._discriminatorMap.has(value)) {
throw new persistenceError_1.PersistenceError("There is already a class in this inheritance hierarchy with a discriminator value of '" + value + "'.");
}
this._discriminatorMap.set(value, mapping);
if (this._baseClass) {
this._baseClass._addDiscriminatorMapping(value, mapping);
}
};
ClassMapping.prototype._ensureRegistry = function () {
if (!this._registry) {
this._registry = new mappingRegistry_1.MappingRegistry();
this._registry.addMapping(this);
if (this._subclasses) {
var subclasses = this._subclasses;
for (var i = 0, l = subclasses.length; i < l; i++) {
this._registry.addMapping(subclasses[i]);
}
}
}
return this._registry;
};
ClassMapping.prototype.read = function (context, value) {
if (value == null)
return null;
var mapping = this.getMapping(context, value);
if (mapping) {
return mapping.readClass(context, value);
}
};
ClassMapping.prototype.getMapping = function (context, document) {
var mapping = this._getMappingForDocument(document);
if (mapping === undefined) {
context.addError("Unknown discriminator value '" + this.getDocumentDiscriminator(document) + "' for class '" + this.name + "'.");
return;
}
return mapping;
};
ClassMapping.prototype._getMappingForDocument = function (document) {
var discriminatorValue = this.getDocumentDiscriminator(document);
if (discriminatorValue === undefined) {
return this;
}
if (this._discriminatorMap) {
return this._discriminatorMap.get(discriminatorValue);
}
};
ClassMapping.prototype.readClass = function (context, value) {
var obj = this.readObject(context, Object.create(this.classConstructor.prototype), value, false);
if ((this.flags & 133120) == 133120) {
obj[OriginalDocument] = value;
}
return obj;
};
ClassMapping.prototype.write = function (context, value) {
if (value == null)
return null;
var originalDocument = value[OriginalDocument];
if (originalDocument != null) {
return originalDocument;
}
var mapping = this._ensureRegistry().getMappingForObject(value);
return (mapping || this).writeClass(context, value, !!mapping);
};
ClassMapping.prototype.writeClass = function (context, value, mappedConstructor) {
var document = {};
if (mappedConstructor) {
this.setDocumentDiscriminator(document);
}
else {
this.setQueryDocumentDiscriminator(document);
}
return this.writeObject(context, document, value);
};
ClassMapping.prototype.areEqual = function (documentValue1, documentValue2) {
if (documentValue1 === documentValue2)
return true;
if (documentValue1 == null || documentValue2 == null)
return false;
var mapping1 = this._getMappingForDocument(documentValue1);
var mapping2 = this._getMappingForDocument(documentValue2);
if (mapping1 === undefined || mapping2 === undefined || mapping1 !== mapping2) {
return false;
}
return mapping1._areEqual(documentValue1, documentValue2);
};
ClassMapping.prototype._areEqual = function (documentValue1, documentValue2) {
return _super.prototype.areEqual.call(this, documentValue1, documentValue2);
};
ClassMapping.prototype.walk = function (session, value, flags, entities, embedded, references) {
if (!value || typeof value !== "object")
return;
return (this._ensureRegistry().getMappingForObject(value) || this)._walk(session, value, flags, entities, embedded, references);
};
ClassMapping.prototype._walk = function (session, value, flags, entities, embedded, references) {
_super.prototype.walk.call(this, session, value, flags, entities, embedded, references);
};
ClassMapping.prototype.fetch = function (session, parentEntity, value, path, depth, callback) {
if (!value || typeof value !== "object") {
process.nextTick(function () { return callback(null, value); });
return;
}
return (this._ensureRegistry().getMappingForObject(value) || this)._fetch(session, parentEntity, value, path, depth, callback);
};
ClassMapping.prototype._fetch = function (session, parentEntity, value, path, depth, callback) {
_super.prototype.fetch.call(this, session, parentEntity, value, path, depth, callback);
};
return ClassMapping;
}(objectMapping_1.ObjectMapping));
exports.ClassMapping = ClassMapping;