entifix-ts-backend
Version:
303 lines • 13.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose = require("mongoose");
const hcSession_1 = require("../../hcSession/hcSession");
const hcMetaData_1 = require("../../hcMetaData/hcMetaData");
class EMSession extends hcSession_1.HcSession {
//#endregion
//#region Methods
constructor() {
super();
}
connect(url, success, error) {
this._mongooseConnection = mongoose.createConnection("mongodb://" + url);
}
getModel(entityName) {
return (this.entitiesInfo.find(e => e.name == entityName).model);
}
getInfo(entityName) {
return this.entitiesInfo.find(info => info.name == entityName).info;
}
//registerEntity<TDocument extends mongoose.Document, TEntity extends EMEntity>(entityName: string, structureSchema : Object, type: { new( session: EMSession, document : EntityDocument ) : TEntity} ) : void
registerEntity(type, entityInfo) {
//var info : EntityInfo = (<any>type).entityInfo;
var structureSchema = entityInfo.getCompleteSchema();
var entityName = entityInfo.name;
if (this.entitiesInfo.filter(e => e.name == entityName).length == 0) {
var schema;
var model;
//schema = <mongoose.Schema>( this._mongooseInstance.Schema(structureSchema) );
schema = new mongoose.Schema(structureSchema);
model = this._mongooseConnection.model(entityName, schema);
this.addEntityInfo({
name: entityName,
info: entityInfo,
schema: schema,
model: model,
activateType: (d) => {
return new type(this, d);
}
});
}
else
console.warn('Attempt to duplicate entity already registered: ' + entityName);
}
createDocument(entityName, document) {
return new Promise((resolve, reject) => {
let model = this.getModel(entityName);
this.manageDocumentCreation(document);
model.create(document).then(value => resolve(value), error => reject(this.createError(error, 'Session: Error in create document')));
});
}
updateDocument(entityName, document) {
return new Promise((resolve, reject) => {
let model = this.getModel(entityName);
this.manageDocumentUpdate(document);
model.findByIdAndUpdate(document._id, document, (error, result) => {
if (!error) {
this.findDocument(entityName, document._id).then(res => resolve(res), err => reject(err));
}
else
reject(this.createError(error, 'Session: Error in update document'));
});
});
}
listDocuments(entityName, options) {
return new Promise((resolve, reject) => {
//PREPARE QUERY =====>>>>>
let skip = options != null && options.skip != null ? options.skip : 0;
let take = options != null && options.take != null ? options.take : null;
//Construct Mongo parameters
let mongoFilters = this.resolveToMongoFilters(entityName, options != null && options.filters != null ? options.filters : null);
if (mongoFilters.error)
reject(this.createError(null, mongoFilters.message));
let mongoSorting = this.resolveToMongoSorting(entityName, options != null && options.sorting != null ? options.sorting : null);
if (mongoSorting != null && mongoSorting.error)
reject(this.createError(null, mongoSorting.message));
//Create Query
let query = this.getModel(entityName).find(mongoFilters.filters);
//Order Query
if (mongoSorting != null && mongoSorting.sorting != null)
query = query.sort(mongoSorting.sorting);
//Limit Query
if (skip > 0)
query = query.skip(skip);
if (take != null)
query = query.limit(take);
//EXECUTE QUERY =====>>>>>
query.exec((error, result) => {
if (!error)
resolve(result);
else
reject(this.createError(error, 'Session: Error in retrive docments'));
});
});
}
findDocument(entityName, id) {
return new Promise((resolve, reject) => {
this.getModel(entityName).where("deferredDeletion").ne(true).where("_id", id).then(res => resolve(res != null && res.length > 0 ? res[0] : null), err => reject(this.createError(err, 'Session: Error in retrive single document')));
});
}
deleteDocument(entityName, document) {
return new Promise((resolve, reject) => {
let model = this.getModel(entityName);
this.manageDocumentDeletion(document);
model.findByIdAndUpdate(document._id, document, (error, result) => {
if (!error)
resolve();
else
reject(this.createError(error, 'Session: Error in delete document'));
});
});
}
activateEntityInstance(name, document) {
return this.entitiesInfo.find(a => a.name == name).activateType(document);
}
getMetadataToExpose(entityName) {
let info = (this.entitiesInfo.find(e => e.name == entityName).info);
return info.getExposedAccessors().map(accessor => {
return {
name: accessor.name,
type: accessor.type,
persistent: (accessor.schema != null || accessor.persistenceType == hcMetaData_1.PersistenceType.Auto)
};
});
}
enableDevMode() {
this._devMode = true;
}
disableDevMode() {
this._devMode = false;
}
createError(error, message) {
if (this._devMode) {
console.warn('DevMode: Error in EMSession: ' + message);
return new EMSessionError(error, message);
}
else
return new EMSessionError(null, 'Internal session error');
}
manageDocumentCreation(document) {
document.created = new Date();
document.deferredDeletion = false;
}
manageDocumentUpdate(document) {
document.modified = new Date();
}
manageDocumentDeletion(document) {
document.deleted = new Date();
document.deferredDeletion = true;
}
resolveToMongoFilters(entityName, filters) {
let info = this.entitiesInfo.find(f => f.name == entityName).info;
//Cambio
let persistentMembers = info.getAllMembers()
.filter(m => (m instanceof hcMetaData_1.AccessorInfo) && (m.schema != null || m.persistenceType == hcMetaData_1.PersistenceType.Auto))
.map(m => {
return { property: m.name, type: m.type, alias: m.persistentAlias };
});
//Filter for defferred deletion.
let mongoFilters;
// Convert all the fixed and optional filters in Mongoose Filetrs
if (filters != null && filters.length > 0) {
//mongoFilters = { $and : [ { deferredDeletion: { $in: [null, false] } } ] };
mongoFilters = { $and: [{ deferredDeletion: false }] };
let opFilters = [];
let errFilters;
//get all filters
for (let filter of filters) {
let pMember = persistentMembers.find(pm => pm.property == filter.property || pm.alias == filter.property);
if (pMember == null) {
errFilters = 'Attempt to filter by a non persistent member';
break;
}
//Single mongo filter
let mongoFilterConversion = this.parseMongoFilter(filter, pMember.type, pMember.property);
if (mongoFilterConversion.err) {
errFilters = mongoFilterConversion.message;
break;
}
if (filter.filterType == FilterType.Fixed)
mongoFilters.$and.push(mongoFilterConversion.value);
if (filter.filterType == FilterType.Optional)
opFilters.push(mongoFilterConversion.value);
}
if (opFilters.length > 0) {
if (opFilters.length > 1)
mongoFilters.$and.push({ $or: opFilters });
else
mongoFilters.$and.push(opFilters[0]);
}
if (errFilters != null)
return { error: true, message: errFilters };
}
else {
//mongoFilters = { deferredDeletion: { $in: [null, false] } };
mongoFilters = { deferredDeletion: false };
}
return { error: false, filters: mongoFilters };
}
parseMongoFilter(f, propertyType, persistentName) {
//Check and convert the filter value
let valueFilter; //value to mongo query
switch (propertyType) {
case 'Number':
if (isNaN(f.value))
return { err: true, message: `The value for a filter in the property "${persistentName}" must be a number` };
else
valueFilter = parseInt(f.value);
break;
default:
valueFilter = f.value;
}
;
//Set the table of conversions for filters and mongo filters
let configConvesions = [
{ operators: ['=', 'eq'] },
{ operators: ['<>', 'ne'], mongoOperator: '$ne' },
{ operators: ['>=', 'gte'], mongoOperator: '$gte', filterTypes: ['Number', 'Date'], },
{ operators: ['<=', 'lte'], mongoOperator: '$lte', filterTypes: ['Number', 'Date'] },
{ operators: ['>', 'gt'], mongoOperator: '$gt', filterTypes: ['Number', 'Date'] },
{ operators: ['<', 'lt'], mongoOperator: '$lt', filterTypes: ['Number', 'Date'] },
{ operators: ['lk'], mongoOperator: '$regex', filterTypes: ['String'], valueModifier: (v) => { return '.*' + v + '.*'; } }
];
//Make the conversion
let confIndex = -1;
let conf = configConvesions.find(cc => cc.operators.find(o => o == f.operator) != null);
if (conf != null) {
valueFilter = conf.valueModifier != null ? conf.valueModifier(valueFilter) : valueFilter;
if (conf.filterTypes == null || (conf.filterTypes != null && conf.filterTypes.find(at => at == propertyType) != null)) {
let value;
if (conf.mongoOperator)
value = { [persistentName]: { [conf.mongoOperator]: valueFilter } };
else
value = { [persistentName]: valueFilter };
return { err: false, value };
}
else
return { err: true, message: `It is not possible to apply the the operator "${f.operator}" to the property "${persistentName}" because it is of type "${propertyType}"` };
}
else
return { err: true, message: `Not valid operator ${f.operator} for filtering` };
}
resolveToMongoSorting(entityName, sorting) {
if (sorting != null && sorting.length > 0) {
let info = this.entitiesInfo.find(f => f.name == entityName).info;
let persistentMembers = info.getAllMembers().filter(m => (m instanceof hcMetaData_1.AccessorInfo) && m.schema != null).map(m => { return { property: m.name, type: m.type }; });
let errSorting;
let mongoSorting = {};
for (let sort of sorting) {
let pMember = persistentMembers.find(pm => pm.property == sort.property);
if (pMember == null) {
errSorting = 'Attempt to sort by a non persistent member';
break;
}
let mst;
if (sort.sortType == SortType.ascending)
mst = 'asc';
if (sort.sortType == SortType.descending)
mst = 'desc';
mongoSorting[sort.property] = mst;
}
if (errSorting != null)
return { error: true, message: errSorting };
return { error: false, sorting: mongoSorting };
}
else
return null;
}
throwException(message) {
if (this._devMode)
console.error('DEV-MODE: ' + message);
else
throw new Error(message);
}
throwInfo(message, warnDevMode) {
warnDevMode = warnDevMode != null ? warnDevMode : true;
if (warnDevMode && this._devMode)
console.warn('DEV-MODE: ' + message);
else
console.info(message);
}
}
exports.EMSession = EMSession;
class EMSessionError {
constructor(error, message) {
this.error = error;
this.message = message;
}
}
exports.EMSessionError = EMSessionError;
var FilterType;
(function (FilterType) {
FilterType[FilterType["Fixed"] = 1] = "Fixed";
FilterType[FilterType["Optional"] = 2] = "Optional";
})(FilterType || (FilterType = {}));
exports.FilterType = FilterType;
var SortType;
(function (SortType) {
SortType[SortType["ascending"] = 1] = "ascending";
SortType[SortType["descending"] = 2] = "descending";
})(SortType || (SortType = {}));
exports.SortType = SortType;
//# sourceMappingURL=emSession.js.map