hydrate-mongodb
Version:
An Object Document Mapper (ODM) for MongoDB.
195 lines (194 loc) • 8.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var async = require("async");
var session_1 = require("./session");
var persister_1 = require("./persister");
var mappingModel_1 = require("./mapping/mappingModel");
var objectUtil_1 = require("./core/objectUtil");
var persistenceError_1 = require("./persistenceError");
var SessionFactoryImpl = (function () {
function SessionFactoryImpl(connection, collections, mappingRegistry) {
this.connection = connection;
this._collections = collections;
this._mappingRegistry = mappingRegistry;
}
SessionFactoryImpl.prototype.createSession = function () {
return new session_1.SessionImpl(this);
};
SessionFactoryImpl.prototype.getCollection = function (ctr) {
var mapping = this.getMappingForConstructor(ctr);
if (!mapping) {
throw new persistenceError_1.PersistenceError("Object type is not mapped as an entity.");
}
return this._collections[mapping.inheritanceRoot.id];
};
SessionFactoryImpl.prototype.getMappingForObject = function (obj) {
var mapping = this._mappingRegistry.getMappingForObject(obj);
if (mapping && (mapping.flags & 1024)) {
return mapping;
}
};
SessionFactoryImpl.prototype.getMappingForConstructor = function (ctr) {
var mapping = this._mappingRegistry.getMappingForConstructor(ctr);
if (mapping && (mapping.flags & 1024)) {
return mapping;
}
};
SessionFactoryImpl.prototype.createPersister = function (session, mapping) {
return new persister_1.PersisterImpl(session, mapping, this._collections[mapping.inheritanceRoot.id]);
};
SessionFactoryImpl.prototype.createIndexes = function (optionsOrCallback, callback) {
var _this = this;
var options;
if (typeof optionsOrCallback === "function") {
callback = optionsOrCallback;
}
else {
options = optionsOrCallback;
}
async.each(this._mappingRegistry.getEntityMappings(), function (mapping, mappingDone) {
var inheritanceRoot = mapping.inheritanceRoot, collection = _this._collections[inheritanceRoot.id], versioned = inheritanceRoot.versioned, versionField = inheritanceRoot.versionField, discriminatorField = inheritanceRoot.discriminatorField;
async.each(mapping.indexes || [], function (index, indexDone) {
var indexOptions = objectUtil_1.shallowClone(index.options) || {};
if (options) {
indexOptions.background = options.background;
}
if (!Array.isArray(index.keys) || index.keys.length == 0) {
indexDone(new persistenceError_1.PersistenceError("Missing or invalid keys on index for '" + mapping.name + "'."));
return;
}
var keys = new Array(index.keys.length);
for (var i = 0; i < index.keys.length; i++) {
var propertyName = index.keys[i][0];
if (!propertyName) {
indexDone(new persistenceError_1.PersistenceError("Missing or invalid key on index for '" + mapping.name + "'."));
return;
}
var order = index.keys[i][1];
if (order !== 1 && order !== -1 && order != 'text') {
indexDone(new persistenceError_1.PersistenceError("Invalid order for key '" + propertyName + "' on index for '" + mapping.name + "'. Order must be 1, -1, or 'text'."));
return;
}
if (propertyName == "_id" || (versioned && propertyName == versionField) || propertyName == discriminatorField) {
keys[i] = index.keys[i];
}
else {
var resolved = mapping.resolve(propertyName);
if (resolved.error) {
indexDone(new persistenceError_1.PersistenceError("Invalid key on index for '" + mapping.name + "': " + resolved.error.message));
return;
}
keys[i] = [resolved.resolvedPath, order];
}
}
for (i = 0; i < mapping.indexes.length; i++) {
if (isPrefixIndex(index, mapping.indexes[i])) {
if (_this.logger) {
_this.logger.trace({
collection: mapping.collectionName,
index: {
keys: keys,
options: indexOptions
}
}, "[Hydrate] Skipping index '" + getIndexName(index) + "' because it's a prefix of '" + getIndexName(mapping.indexes[i]) + " on '" + collection.collectionName + "' collection'.");
}
process.nextTick(indexDone);
return;
}
}
for (i = mapping.indexes.indexOf(index) + 1; i < mapping.indexes.length; i++) {
if (areIndexesEqual(index, mapping.indexes[i])) {
if (_this.logger) {
_this.logger.trace({
collection: mapping.collectionName,
index: {
keys: keys,
options: indexOptions
}
}, "[Hydrate] Skipping index '" + getIndexName(index) + "' because it's identical to '" + getIndexName(mapping.indexes[i]) + " on '" + collection.collectionName + "' collection'.");
}
process.nextTick(indexDone);
return;
}
}
collection.createIndex(keys, indexOptions, function (err, indexName) {
if (err)
return indexDone(err);
if (_this.logger) {
_this.logger.trace({
collection: mapping.collectionName,
index: {
keys: keys,
options: indexOptions
}
}, "[Hydrate] Ensured index '" + indexName + "' exists on '" + collection.collectionName + "' collection.");
}
indexDone();
});
}, mappingDone);
}, callback);
};
SessionFactoryImpl.prototype.dropIndexes = function (callback) {
var _this = this;
async.each(this._mappingRegistry.getEntityMappings().filter(function (mapping) { return mapping.hasFlags(4096); }), function (mapping, done) {
var collection = _this._collections[mapping.id];
if (collection) {
collection.dropIndexes(function (err) {
if (err)
return done(err);
if (_this.logger) {
_this.logger.trace({
collection: mapping.collectionName
}, "[Hydrate] Dropped all indexes on '" + collection.collectionName + "' collection.");
}
done();
});
}
}, callback);
};
return SessionFactoryImpl;
}());
exports.SessionFactoryImpl = SessionFactoryImpl;
function isPrefixIndex(index1, index2) {
if (index1 === index2) {
return false;
}
if (index1.keys.length >= index2.keys.length) {
return false;
}
if (!objectUtil_1.shallowEqual(index1.options, index2.options)) {
return false;
}
var key1, key2;
for (var i = 0; i < index1.keys.length; i++) {
key1 = index1.keys[i];
key2 = index2.keys[i];
if (key1[0] !== key2[0] || key1[1] !== key2[1]) {
return false;
}
}
return true;
}
function areIndexesEqual(index1, index2) {
if (index1 === index2) {
return true;
}
if (index1.keys.length != index2.keys.length) {
return false;
}
if (!objectUtil_1.shallowEqual(index1.options, index2.options)) {
return false;
}
var key1, key2;
for (var i = 0; i < index1.keys.length; i++) {
key1 = index1.keys[i];
key2 = index2.keys[i];
if (key1[0] !== key2[0] || key1[1] !== key2[1]) {
return false;
}
}
return true;
}
function getIndexName(index) {
return index.keys.map(function (x) { return x.join("_"); }).join("_");
}