UNPKG

hydrate-mongodb

Version:
287 lines (286 loc) 11.7 kB
"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 mappingBase_1 = require("./mappingBase"); var mappingModel_1 = require("./mappingModel"); var persistenceError_1 = require("../persistenceError"); var ObjectMapping = (function (_super) { __extends(ObjectMapping, _super); function ObjectMapping() { var _this = _super.call(this, 64 | 2048) || this; _this.properties = []; _this._propertiesByName = new Map(); _this._propertiesByField = new Map(); return _this; } ObjectMapping.prototype.addProperty = function (property) { if (!property) { throw new persistenceError_1.PersistenceError("Missing required argument 'property'."); } var error = this.validateProperty(property); if (error) { throw new persistenceError_1.PersistenceError(error); } this._propertiesByName.set(property.name, property); if (property.field) { this._propertiesByField.set(property.field, property); } this.properties.push(property); return property; }; ObjectMapping.prototype.validateProperty = function (property) { if (!property.name) { return "Property is missing 'name'."; } if (!property.field && !property.hasFlags(1)) { return "Property must define a 'field' mapping if the property is not ignored."; } if (this._propertiesByName.has(property.name)) { return "There is already a mapped property with the name '" + property.name + "'."; } if (this._propertiesByField.has(property.field)) { return "There is already a mapped property for field '" + property.field + "'."; } }; ObjectMapping.prototype.getProperty = function (name) { if (!name) { throw new persistenceError_1.PersistenceError("Missing required argument 'name'."); } return this._propertiesByName.get(name); }; ObjectMapping.prototype.getPropertyForField = function (field) { return this._propertiesByField.get(field); }; ObjectMapping.prototype.getProperties = function (flags) { if (!flags) { return this.properties; } var ret = []; var properties = this.properties; for (var i = 0, l = properties.length; i < l; i++) { var property = properties[i]; if ((property.flags & flags) !== 0) { ret.push(property); } } return ret; }; ObjectMapping.prototype.read = function (context, value) { return this.readObject(context, {}, value, false); }; ObjectMapping.prototype.readObject = function (context, obj, value, checkRemoved) { if (value == null) { return null; } if (typeof value !== "object") { context.addError("Expected value to be an object."); return; } var base = context.path ? context.path + "." : "", properties = this.properties; var objectParent = context.parent; context.parent = obj; for (var i = 0, l = properties.length; i < l; i++) { var property = properties[i]; if ((property.flags & 4096) != 0) { property.setPropertyValue(obj, objectParent); continue; } if ((property.flags & (1 | 64 | 512)) != 0) { continue; } var fieldValue = property.getFieldValue(value), propertyValue = undefined; if (fieldValue !== undefined) { if (fieldValue === null) { if (property.nullable) { propertyValue = null; } } else { var savedPath = context.path; context.path = base + property.name; if ((property.flags & 1024) != 0) { context.addFetch(context.path); } propertyValue = property.mapping.read(context, fieldValue); context.path = savedPath; } } if (propertyValue !== undefined) { property.setPropertyValue(obj, propertyValue); } else { if (checkRemoved && property.getPropertyValue(obj) !== undefined) { property.setPropertyValue(obj, undefined); } } } context.parent = objectParent; if (context.observer && (this.flags & 131072) == 0) { context.observer.watch(obj); } return obj; }; ObjectMapping.prototype.write = function (context, value) { return this.writeObject(context, {}, value); }; ObjectMapping.prototype.writeObject = function (context, document, value) { if (value == null) return null; var base = context.path ? context.path + "." : "", properties = this.properties, fieldValue; if (this.flags & 2048) { if (context.visited.indexOf(value) !== -1) { context.addError("Recursive reference of embedded object is not allowed."); return; } context.visited.push(value); } for (var i = 0, l = properties.length; i < l; i++) { var property = properties[i], flags = property.flags; if ((flags & (1 | 64)) != 0) { continue; } var propertyValue = property.getPropertyValue(value); if (propertyValue === undefined) { continue; } if (propertyValue === null) { if (!property.nullable) { continue; } fieldValue = null; } else { var savedPath = context.path; context.path = base + property.name; fieldValue = property.mapping.write(context, propertyValue); context.path = savedPath; } property.setFieldValue(document, fieldValue); } context.visited.pop(); return document; }; ObjectMapping.prototype.watch = function (value, observer, visited) { if (!value || typeof value != "object") return; if (this.flags & 2048) { if (visited.indexOf(value) !== -1) return; visited.push(value); } observer.watch(value); for (var i = 0, l = this.properties.length; i < l; i++) { var property = this.properties[i]; if ((property.flags & 1) == 0) { property.mapping.watch(property.getPropertyValue(value), observer, visited); } } }; ObjectMapping.prototype.areEqual = function (documentValue1, documentValue2) { if (documentValue1 === documentValue2) return true; if (documentValue1 == null || documentValue2 == null) return false; if (typeof documentValue1 !== "object" || typeof documentValue2 !== "object") { return false; } var properties = this.properties; for (var i = 0, l = properties.length; i < l; i++) { var property = properties[i]; if ((property.flags & (1 | 64)) != 0) { continue; } var fieldValue1 = property.getFieldValue(documentValue1); var fieldValue2 = property.getFieldValue(documentValue2); if (fieldValue1 !== fieldValue2 && !property.mapping.areEqual(fieldValue1, fieldValue2)) { return false; } } return true; }; ObjectMapping.prototype.walk = function (session, value, flags, entities, embedded, references) { if (!value || typeof value !== "object") return; if (this.flags & 2048) { if (embedded.indexOf(value) !== -1) return; embedded.push(value); } var properties = this.properties; for (var i = 0, l = properties.length; i < l; i++) { var property = properties[i]; if ((property.flags & 1) == 0 && ((property.flags & flags) != 0 || ((flags & 8063) == 0))) { property.mapping.walk(session, property.getPropertyValue(value), flags, entities, embedded, references); } } }; ObjectMapping.prototype.fetch = function (session, parentEntity, value, path, depth, callback) { if (!value || typeof value !== "object" || depth == path.length) { process.nextTick(function () { return callback(null, value); }); return; } var property = this.getProperty(path[depth]); if (property === undefined) { return callback(new persistenceError_1.PersistenceError("Undefined property '" + path[depth] + "' in path '" + path.join(".") + "'.")); } var propertyValue = property.getPropertyValue(value); if ((property.flags & 64) != 0 && propertyValue === undefined) { property.mapping.fetchInverse(session, parentEntity, property.inverseOf, path, depth + 1, handleCallback); } else if ((property.flags & 2048) != 0 && propertyValue === undefined) { this.fetchPropertyValue(session, value, property, handleCallback); } else { property.mapping.fetch(session, parentEntity, propertyValue, path, depth + 1, handleCallback); } function handleCallback(err, result) { if (err) return callback(err); if (propertyValue !== result) { property.setPropertyValue(value, result); } callback(null, value); } }; ObjectMapping.prototype.fetchPropertyValue = function (session, value, property, callback) { process.nextTick(function () { return callback(null, property.getPropertyValue(value)); }); }; ObjectMapping.prototype.resolveCore = function (context) { var property = this.getProperty(context.currentProperty); if (property === undefined) { if ((this.flags & 4) != 0) { context.setError("Undefined property for class '" + this.name + "'."); } else { context.setError("Undefined property."); } return; } if ((property.flags & 4096) != 0) { context.setError("Cannot resolve parent reference."); } else if ((property.flags & 64) != 0) { context.setError("Cannot resolve inverse side of relationship."); } else if ((property.flags & 1) != 0) { context.setError("Cannot resolve ignored property."); } if (context.resolveProperty(property.mapping, property.field)) { return; } property.mapping.resolve(context); }; return ObjectMapping; }(mappingBase_1.MappingBase)); exports.ObjectMapping = ObjectMapping;