UNPKG

vulcain-corejs

Version:
310 lines (308 loc) 13.6 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments)).next()); }); }; const annotations_1 = require("./../../di/annotations"); const requestContext_1 = require("./../../servers/requestContext"); const mongodb_1 = require("mongodb"); const annotations_2 = require("../../di/annotations"); const applicationRequestError_1 = require("../../errors/applicationRequestError"); const system_1 = require("../../configurations/globals/system"); /** * Default mongo provider */ let MongoProvider = class MongoProvider { constructor(_logger, ctx, uri, options) { this._logger = _logger; this.ctx = ctx; this.options = options; this.options = this.options || {}; // Try to fix topology was destroy error this.options.socketOptions = this.options.socketOptions || { noDelay: true, connectTimeoutMS: 0, socketTimeoutMS: 0 }; this.state = { uri: uri }; } get address() { return this.state.uri; } initializeWithSchemaAsync(tenant, schema) { if (!schema) throw new Error("schema is not set for provider."); if (!tenant) throw new Error("tenant is required"); this.state.uri = this.state.uri + "/" + tenant; this.state.keyPropertyName = schema.getIdProperty() || "_id"; this.ctx.logVerbose(`MONGODB: Creating provider ${this.state.uri} for schema ${schema.name}`); let keys; for (let p in schema.description.properties) { if (!schema.description.properties.hasOwnProperty(p)) continue; let prop = schema.description.properties[p]; if (prop.unique) { if (!keys) keys = {}; keys[p] = prop.unique === true ? 1 : prop.unique; } } const state = this.state; const options = this.options; return new Promise((resolve, reject) => { // Don't use this here to avoid memory leaks // Open connexion mongodb_1.MongoClient.connect(state.uri, options, (err, db) => { if (err) { reject(err); system_1.System.log.error(null, err, `MONGODB: Error when opening database ${state.uri} for schema ${schema.name}`); return; } state._mongo = db; state.dispose = () => { db.close(); }; if (keys) { let indexName = schema.description.storageName + "_uniqueIndex"; db.createIndex(schema.description.storageName, keys, { w: 1, background: true, name: indexName, unique: true }, (err) => { if (err) { system_1.System.log.error(null, err, `MONGODB: Error when creating index for ${state.uri} for schema ${schema.name}`); } else { system_1.System.log.info(null, `MONGODB: Unique index created for ${state.uri} for schema ${schema.name}`); } }); } resolve(state); }); }); } /** * Return a list of entities * @param options * @returns {Promise} */ getAllAsync(schema, options) { let page = options.page || 0; let maxByPage = options.maxByPage || 100; let query = options.query ? options.query.filter || options.query : {}; this.ctx.logVerbose(`MONGODB: Get all on ${this.state.uri} for schema ${schema.name} with query: ${JSON.stringify(query)}`); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { let db = this.state._mongo; let cursor = db.collection(schema.description.storageName).find(query) .skip(page * maxByPage) .limit(maxByPage); cursor.toArray((err, res) => { if (err) { this.ctx.logError(err, `Error when getting all entities for schema: ${schema.name}`); reject(err); } else resolve(res); }); } catch (err) { this.ctx.logError(err, `Error when getting all entities for schema: ${schema.name}`); reject(err); } })); } findOneAsync(schema, query) { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { let db = this.state._mongo; db.collection(schema.description.storageName).findOne(query, (err, res) => { if (err) { this.ctx.logError(err, `Error when find one entity for schema: ${schema.name}`); reject(err); } else resolve(res); }); } catch (err) { this.ctx.logError(err, `Error when find one entity for schema: ${schema.name}`); reject(err); } })); } /** * Read an entity * @param name * @returns {Promise} */ getAsync(schema, name) { this.ctx.logVerbose(`MONGODB: Get on ${this.state.uri} for schema ${schema.name} with id: ${name}`); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { let filter = {}; filter[this.state.keyPropertyName || "_id"] = name; let db = this.state._mongo; db.collection(schema.description.storageName).findOne(filter, (err, res) => { if (err) { this.ctx.logError(err, `Error when getting entity ${name}, schema: ${schema.name}`); reject(this.normalizeErrors(name, err)); } else resolve(res); }); } catch (err) { this.ctx.logError(err, `Error when getting entity ${name}, schema: ${schema.name}`); reject(err); } })); } /** * Delete an entity * @param id * @returns {Promise} */ deleteAsync(schema, old) { if (!old) throw new Error("Argument is required"); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { let id; if (typeof old === "string") id = old; else id = old[this.state.keyPropertyName]; if (!id) throw new Error("Mongo : Error on delete. Id must not be null"); try { let filter = {}; filter[this.state.keyPropertyName || "_id"] = id; this.ctx.logVerbose(`MONGODB: Deleting on ${this.state.uri} for schema ${schema.name} with filter: ${JSON.stringify(filter)}`); let db = this.state._mongo; db.collection(schema.description.storageName).remove(filter, (err, res) => { if (err) { this.ctx.logError(err, `Error when deleting entity ${id}, schema: ${schema.name}`); reject(this.normalizeErrors(id, err)); } else resolve(); }); } catch (err) { this.ctx.logError(err, `Error when deleting entity ${id}, schema: ${schema.name}`); reject(err); } })); } normalizeErrors(id, err) { if (!err || !err.errors) return err; let error = new applicationRequestError_1.ApplicationRequestError("Mongo error", []); if (err.errors) { for (let e in err.errors) { if (!err.errors.hasOwnProperty(e)) continue; let error = err.errors[e]; error.errors.push({ message: error.message, property: error.path, id: id }); } } return error; } /** * Persist an entity * @param entity * @returns {Promise} */ createAsync(schema, entity) { if (!entity) throw new Error("Entity is required"); entity._created = new Date().toUTCString(); this.ctx.logVerbose(`MONGODB: Create entity on ${this.state.uri} for schema ${schema.name} with entity: ${JSON.stringify(entity)}`); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { let db = this.state._mongo; db.collection(schema.description.storageName).insertOne(entity, (err) => { if (err) { let id = entity[this.state.keyPropertyName]; this.ctx.logError(err, `Error when creating entity ${id}, schema: ${schema.name}`); reject(this.normalizeErrors(entity[this.state.keyPropertyName], err)); } else { resolve(entity); } }); } catch (err) { reject(err); } })); } /** * Update an entity * @param entity * @param old * @returns {Promise<T>} */ updateAsync(schema, entity, old) { if (!entity) throw new Error("Entity is required"); this.ctx.logVerbose(`MONGODB: Update entity on ${this.state.uri} for schema ${schema.name} with entity: ${JSON.stringify(entity)}`); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { try { let id = (old || entity)[this.state.keyPropertyName]; let filter = {}; filter[this.state.keyPropertyName || "_id"] = id; let db = this.state._mongo; let collection = db.collection(schema.description.storageName); collection.findOne(filter, (err, initial) => { if (err) { this.ctx.logError(err, `Error when updating entity ${id}, schema: ${schema.name}`); reject(new Error(`Error when updating entity ${id}, schema: ${schema.name}, error: ${err.message}`)); return; } if (!initial) { err = new Error(`Can not update unknow entity ${id}, schema: ${schema.name}`); this.ctx.logError(err, `Error when updating entity ${id}, schema: ${schema.name}`); reject(); return; } let _id = initial._id; initial = schema.deepAssign(initial, entity); initial._updated = new Date().toUTCString(); initial._id = _id; collection.updateOne(filter, initial, err => { if (err) { this.ctx.logError(err, `Error when updating entity ${id}, schema: ${schema.name}`); reject(this.normalizeErrors(id, err)); } else resolve(initial); }); }); } catch (err) { reject(err); } })); } }; MongoProvider = __decorate([ __param(0, annotations_2.Inject(annotations_1.DefaultServiceNames.Logger)), __param(1, annotations_2.Inject(annotations_1.DefaultServiceNames.RequestContext, true)), __metadata("design:paramtypes", [Object, requestContext_1.RequestContext, String, Object]) ], MongoProvider); exports.MongoProvider = MongoProvider; //# sourceMappingURL=provider.js.map