UNPKG

claire-framework

Version:

- được viết bằng TypeScript - hỗ trợ websocket và HTTP request - hỗ trợ CLI để generate base project (claire-cli)

456 lines 41.1 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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 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) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const mongoose_1 = __importStar(require("mongoose")); const AbstractQuery_1 = require("../model/AbstractQuery"); const ClaireError_1 = require("../system/ClaireError"); const errors_1 = require("../system/errors"); const DataType_1 = require("../enum/DataType"); const QueryOperator_1 = require("../model/QueryOperator"); const Utils_1 = require("../system/Utils"); const AbstractDatabaseAdapter_1 = require("../database/AbstractDatabaseAdapter"); const AbstractLogger_1 = require("../logger/AbstractLogger"); const core_1 = require("../decorator/core"); class ModelAdapter extends AbstractQuery_1.AbstractQuery { constructor(model, metadata, schema, sequenceProvider, session) { super(model, metadata); this.sequenceProvider = sequenceProvider; this.session = session; this.currentSchema = schema; } getQueryOptions() { const opt = {}; if (this.session) { opt.session = this.session; } return opt; } saveOne(modelInstance) { return __awaiter(this, void 0, void 0, function* () { //-- use mongoose create function let result = yield this.saveMany([modelInstance]); return result[0]; }); } saveMany(modelInstances) { return __awaiter(this, void 0, void 0, function* () { //-- apply default data values //-- use mongoose bulkWrite function let dataObjects = this.convertToDataObjects(modelInstances); const defaultDataValues = this.convertToDataObjects([this.currentMetadata.getDefaultLogicValues()])[0]; dataObjects = dataObjects.map((obj) => (Object.assign(Object.assign({}, defaultDataValues), Utils_1.Utils.getCleanObject(obj)))); let result = yield this.currentSchema.modelConnection.insertMany(dataObjects, this.getQueryOptions()); if (!result || result.length !== modelInstances.length) { throw new ClaireError_1.ClaireError(errors_1.BULK_OPERATION_ERROR); } let instances = []; let primaryKey = this.currentMetadata.getPrimaryKey(); try { if (primaryKey.isAutoIncrement) { let operations = []; let sequences = []; if (Utils_1.Utils.isIntegerDataTypes(primaryKey.innerDataType)) { //-- update sequential ids for inserted records for (let i = 0; i < result.length; i++) { let id = yield this.sequenceProvider.getNextSequence(this.currentMetadata.tableName); operations.push({ updateOne: { filter: { _id: result[i]["_id"] }, update: { [primaryKey.fieldDataName]: id } } }); sequences.push(id); } } else { //-- up for (let i = 0; i < result.length; i++) { let id = result[i]["_id"]; operations.push({ updateOne: { filter: { _id: id }, update: { [primaryKey.fieldDataName]: id } } }); sequences.push(id); } } //-- call bulkWrite to update ids yield this.currentSchema.modelConnection.bulkWrite(operations, this.getQueryOptions()); //-- update primary key value in returned values for (let i = 0; i < modelInstances.length; i++) { // @ts-ignore instances.push(Object.assign(Object.assign({}, this.defaultLogicValues), modelInstances[i], { [primaryKey.fieldLogicName]: sequences[i] })); } } else { for (let i = 0; i < modelInstances.length; i++) { // @ts-ignore instances.push(Object.assign(Object.assign({}, this.defaultLogicValues), modelInstances[i])); } } return instances; } catch (err) { throw new ClaireError_1.ClaireError(errors_1.QUERY_ERROR, err.stack || String(err)); } }); } updateQueryByOptions(query, options) { if (options) { if (options.order) { // @ts-ignore const dataOrder = this.convertToDataObjects([options.order])[0]; query = query.sort(dataOrder); } if (options.projection) { let projection = this.getProjectionFields(options.projection).reduce((collector, fieldName) => (Object.assign(Object.assign({}, collector), { [fieldName]: 1 })), { "_id": 0 }); query = query.select(projection); } if (options.limit) { query = query.limit(options.limit); if (options.page) { //-- page in mongoose starts with 0 query = query.skip(options.limit * (options.page - 1)); } } } return query; } getOne(queries, options) { return __awaiter(this, void 0, void 0, function* () { let queryObject = this.getQueryObjectFromQueryConditions(queries || []); let query = this.currentSchema.modelConnection.findOne(queryObject, undefined, this.getQueryOptions()); query = this.updateQueryByOptions(query, options); let instance = yield query.lean().exec(); if (!instance) { return undefined; } return this.convertToLogicObjects([instance], options && options.projection)[0]; }); } getMany(queries, options) { return __awaiter(this, void 0, void 0, function* () { let rawQuery = this.getQueryObjectFromQueryConditions(queries || []); //-- use mongoose find function let query = this.currentSchema.modelConnection.find(rawQuery, undefined, this.getQueryOptions()); query = this.updateQueryByOptions(query, options); let result = yield query.lean().exec(); return this.convertToLogicObjects(result, options && options.projection); }); } deleteOne(modelInstance) { return __awaiter(this, void 0, void 0, function* () { let primaryKey = this.currentMetadata.getPrimaryKey(); //-- construct query object // @ts-ignore let queryObject = this.getQueryObjectFromQueryConditions([{ [primaryKey.fieldDataName]: eq(modelInstance[primaryKey.fieldDataName]) }]); try { yield this.currentSchema.modelConnection.findOneAndRemove(queryObject, this.getQueryOptions()); return modelInstance; } catch (err) { throw new ClaireError_1.ClaireError(errors_1.QUERY_ERROR, err.stack || err); } }); } deleteMany(queries) { return __awaiter(this, void 0, void 0, function* () { let rawQuery = this.getQueryObjectFromQueryConditions(queries); //-- use mongoose deleteMany function try { let result = yield this.currentSchema.modelConnection.deleteMany(rawQuery, this.getQueryOptions()); return result["deletedCount"]; } catch (err) { throw new ClaireError_1.ClaireError(errors_1.QUERY_ERROR, err.stack || String(err)); } }); } updateOne(modelInstance) { return __awaiter(this, void 0, void 0, function* () { try { yield this.currentSchema.modelConnection.findOneAndUpdate( // @ts-ignore { [this.currentMetadata.getPrimaryKey().fieldDataName]: modelInstance[this.currentMetadata.getPrimaryKey().fieldDataName] }, // @ts-ignore this.convertToDataObjects(modelInstance), this.getQueryOptions()); return modelInstance; } catch (err) { throw new ClaireError_1.ClaireError(errors_1.QUERY_ERROR, err.stack || err); } }); } updateMany(queries, update) { return __awaiter(this, void 0, void 0, function* () { let rawQuery = this.getQueryObjectFromQueryConditions(queries); //-- use mongoose updateMany function try { let result = yield this.currentSchema.modelConnection.updateMany(rawQuery, this.convertToDataObjects([update])[0], this.getQueryOptions()); return result["ok"]; } catch (err) { throw new ClaireError_1.ClaireError(errors_1.QUERY_ERROR, err.stack || String(err)); } }); } rawQuery(query) { throw new ClaireError_1.ClaireError(errors_1.NOT_SUPPORTED); } getQueryObjectFromQueryConditions(queries) { if (!queries || !queries.length) { return {}; } const orQueries = []; for (const query of queries) { let result = {}; Object.keys(query).forEach((key) => { // @ts-ignore let operator = query[key]; let dataKey = this.currentMetadata.getFieldByLogicName(key).fieldDataName; switch (operator.operator) { case QueryOperator_1.Operator.COMMON_EQUALITY: result[dataKey] = { $eq: operator.value }; break; case QueryOperator_1.Operator.COMMON_INEQUALITY: result[dataKey] = { $ne: operator.value }; break; case QueryOperator_1.Operator.COMMON_BELONG: result[dataKey] = { $in: operator.value }; break; case QueryOperator_1.Operator.STRING_CONTAIN: result[dataKey] = { $regex: new RegExp(`.*${Utils_1.Utils.escapeRegExp(operator.value)}.*`), }; break; case QueryOperator_1.Operator.STRING_REGEX: result[dataKey] = { $regex: new RegExp(operator.value), }; break; case QueryOperator_1.Operator.NUMBER_GT: result[dataKey] = { $gt: operator.value }; break; case QueryOperator_1.Operator.NUMBER_GTE: result[dataKey] = { $gte: operator.value }; break; case QueryOperator_1.Operator.NUMBER_LT: result[dataKey] = { $lt: operator.value }; break; case QueryOperator_1.Operator.NUMBER_LTE: result[dataKey] = { $lte: operator.value }; break; case QueryOperator_1.Operator.NUMBER_BETWEEN: result[dataKey] = { $and: [{ $gte: operator.value.start }, { $lte: operator.value.end }] }; break; } }); orQueries.push(result); } return { $or: orQueries }; } } class TransactionAdapter { constructor(session, sequenceProvider, modelMetaData, schemas) { this.session = session; this.sequenceProvider = sequenceProvider; this.modelAdapters = new Map(); this.modelMetadata = modelMetaData; this.schemas = schemas; } use(model) { let modelAdapter = this.modelAdapters.get(model.name); if (!modelAdapter) { modelAdapter = new ModelAdapter(model, this.modelMetadata.find((meta) => meta.modelName === model.name), this.schemas[model.name], this.sequenceProvider, this.session); this.modelAdapters.set(model.name, modelAdapter); } // @ts-ignore return modelAdapter; } commit() { return __awaiter(this, void 0, void 0, function* () { return this.session.commitTransaction(); }); } rollback() { return __awaiter(this, void 0, void 0, function* () { return this.session.abortTransaction(); }); } } class DefaultNoSqlAdapter extends AbstractDatabaseAdapter_1.AbstractDatabaseAdapter { constructor(provider, connectionString) { super(); this.connectionString = connectionString; this.modelAdapters = new Map(); this.provider = provider; } init() { const _super = Object.create(null, { init: { get: () => super.init } }); return __awaiter(this, void 0, void 0, function* () { yield _super.init.call(this); //-- connect to mongodb mongoose_1.default.set("useNewUrlParser", true); mongoose_1.default.set("useFindAndModify", false); mongoose_1.default.set("useCreateIndex", true); mongoose_1.default.set("useUnifiedTopology", true); this.logger.debug('Connecting to mongodb...'); let result = yield new Promise(resolve => { mongoose_1.default.connect(`mongodb://${this.connectionString}`) .then((mongo) => { this.connection = mongo; return resolve(true); }) .catch((err) => { return resolve(new ClaireError_1.ClaireError("INTERNAL_SYSTEM_ERROR", err.stack || String(err))); }); }); if (result instanceof ClaireError_1.ClaireError) { throw result; } this.logger.debug('Generating in-memory schemas...'); //-- create in-memory schemas for (let i = 0; i < this.models.length; i++) { let model = this.models[i]; let meta = this.modelMetadata.find((meta) => meta.modelName === model.name); if (!meta) { throw new ClaireError_1.ClaireError(errors_1.MODEL_METADATA_NOT_FOUND, model.name); } //-- inject modelConnection this.schemas[model.name].modelConnection = this.connection.model(model.name, this.getSchemaFromPrototype(meta), meta.tableName); } //-- build counter schema let counterSchema = { tableName: { type: String, }, counter: { type: Number, }, }; this.counterSchema = this.connection.model("_counter", counterSchema, "_counter"); }); } stop() { const _super = Object.create(null, { stop: { get: () => super.stop } }); return __awaiter(this, void 0, void 0, function* () { this.logger.debug("Disconnecting from database..."); this.connection.disconnect(); yield _super.stop.call(this); }); } getSchemaFromPrototype(prototype) { let result = {}; prototype.fields.forEach((field) => { let fieldProperties = {}; //-- default is not null Object.assign(fieldProperties, { required: !field.nullable }); if (field.isPrimaryKey) { if (!field.isAutoIncrement) { //-- if not auto then must be unique Object.assign(fieldProperties, { unique: true }); } //-- allow empty for insert later Object.assign(fieldProperties, { required: false, sparse: true }); } if (field.isForeignKey === true) { let referModel = this.modelMetadata.find((meta) => meta.modelName === field.referModel); Object.assign(fieldProperties, { type: mongoose_1.default.Types.ObjectId, ref: referModel && referModel.tableName, required: true }); } if (field.isUnique === true) { Object.assign(fieldProperties, { unique: true }); if (field.nullable) { Object.assign(fieldProperties, { sparse: true }); } } if (field.defaultValue !== undefined && typeof field.defaultValue !== "function") { Object.assign(fieldProperties, { default: field.defaultValue }); } switch (field.innerDataType) { case DataType_1.DataType.TEXT: case DataType_1.DataType.STRING: Object.assign(fieldProperties, { type: mongoose_1.Schema.Types.String }); break; case DataType_1.DataType.INTEGER: case DataType_1.DataType.FLOAT: case DataType_1.DataType.BIGINT: Object.assign(fieldProperties, { type: mongoose_1.Schema.Types.Number }); break; case DataType_1.DataType.BOOL: Object.assign(fieldProperties, { type: mongoose_1.Schema.Types.Boolean }); break; case DataType_1.DataType.ARRAY: Object.assign(fieldProperties, { type: mongoose_1.Schema.Types.Mixed }); break; } result[field.fieldDataName] = fieldProperties; }); return result; } use(model) { let modelAdapter = this.modelAdapters.get(model.name); if (!modelAdapter) { modelAdapter = new ModelAdapter(model, this.modelMetadata.find((meta) => meta.modelName === model.name), this.schemas[model.name], this); this.modelAdapters.set(model.name, modelAdapter); } // @ts-ignore return modelAdapter; } getNextSequence(tableName) { return __awaiter(this, void 0, void 0, function* () { try { let result = yield this.counterSchema.findOneAndUpdate({ tableName }, { $inc: { counter: 1 } }, { new: true, upsert: true, rawResult: true }); return result["value"]["counter"]; } catch (err) { throw new ClaireError_1.ClaireError(errors_1.QUERY_ERROR, err.stack || String(err)); } }); } createTransaction() { return __awaiter(this, void 0, void 0, function* () { let session = yield this.connection.startSession(); session.startTransaction(); return new TransactionAdapter(session, this, this.modelMetadata, this.schemas); }); } } __decorate([ core_1.Inject(), __metadata("design:type", AbstractLogger_1.AbstractLogger) ], DefaultNoSqlAdapter.prototype, "logger", void 0); exports.DefaultNoSqlAdapter = DefaultNoSqlAdapter; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVmYXVsdE5vU3FsQWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9kZWZhdWx0LWltcGxlbWVudGF0aW9ucy9EZWZhdWx0Tm9TcWxBZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFEQUEwQztBQUMxQywwREFBcUQ7QUFHckQsdURBQWtEO0FBQ2xELDZDQUE0RztBQUM1RywrQ0FBMEM7QUFFMUMsMERBQWdEO0FBQ2hELDJDQUFzQztBQUV0QyxpRkFBMkY7QUFDM0YsNkRBQXdEO0FBQ3hELDRDQUF5QztBQU96QyxNQUFNLFlBQWdCLFNBQVEsNkJBQWdCO0lBTTFDLFlBQ0ksS0FBMkMsRUFDM0MsUUFBdUIsRUFDdkIsTUFBZ0MsRUFDaEMsZ0JBQWtDLEVBQ2xDLE9BQWE7UUFFYixLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztRQUN6QyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztJQUNoQyxDQUFDO0lBRU8sZUFBZTtRQUNuQixNQUFNLEdBQUcsR0FBUSxFQUFFLENBQUM7UUFDcEIsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2QsR0FBRyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1NBQzlCO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDO0lBRVksT0FBTyxDQUFDLGFBQXlCOztZQUMxQyxpQ0FBaUM7WUFDakMsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUNsRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixDQUFDO0tBQUE7SUFFWSxRQUFRLENBQUMsY0FBNEI7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