1 | "use strict";
|
2 | const utils_1 = require('../core/utils');
|
3 | const Sequelize = require("sequelize");
|
4 | const Q = require('q');
|
5 | const model_entity_1 = require('../core/dynamic/model-entity');
|
6 | const constants_1 = require('../core/constants');
|
7 | const Enumerable = require('linq');
|
8 | const principalContext_1 = require('../security/auth/principalContext');
|
9 | const constantKeys_1 = require('../core/constants/constantKeys');
|
10 | var queryString = require('qs');
|
11 | class SequelizeService {
|
12 | constructor() {
|
13 | this._schemaCollection = {};
|
14 | this._relationCollection = [];
|
15 | }
|
16 | init(force) {
|
17 | force = force || false;
|
18 | return this.sequelize.sync({ force: force, logging: true });
|
19 | }
|
20 | connect() {
|
21 | if (utils_1.config().SqlConfig.isSqlEnabled == false)
|
22 | return;
|
23 | this.sequelize = new Sequelize(utils_1.config().SqlConfig.database, utils_1.config().SqlConfig.username, utils_1.config().SqlConfig.password, utils_1.config().SqlConfig.sequlizeSetting);
|
24 | }
|
25 | getSqlContext() {
|
26 | return this.sequelize;
|
27 | }
|
28 | startTransaction(param) {
|
29 | return this.sequelize.transaction();
|
30 | }
|
31 | commitTransaction(param) {
|
32 | return param.commit();
|
33 | }
|
34 | rollbackTransaction(param) {
|
35 | return param.rollback();
|
36 | }
|
37 | getCustomResult(databaseName, query) {
|
38 | if (utils_1.config().SqlConfig.isSqlEnabled == false)
|
39 | return;
|
40 | var dynamicSequelize = new Sequelize(databaseName, utils_1.config().SqlConfig.username, utils_1.config().SqlConfig.password, utils_1.config().SqlConfig.sequlizeSetting);
|
41 | return dynamicSequelize.query(query);
|
42 | }
|
43 | addScheam(name, schema, detail) {
|
44 | var newSchema = this.sequelize.define(name, schema, detail);
|
45 | this._schemaCollection[name] = newSchema;
|
46 | return newSchema;
|
47 | }
|
48 | addRelationInSchema(fromSchema, toSchema, relationType, metaData) {
|
49 | let path = metaData.propertyKey;
|
50 | if (relationType == constants_1.Decorators.ONETOMANY)
|
51 | fromSchema.hasMany(toSchema, { as: path, foreignKey: metaData.foreignKey });
|
52 | if (relationType == constants_1.Decorators.MANYTOONE)
|
53 | fromSchema.belongsTo(toSchema, { as: path, foreignKey: metaData.foreignKey });
|
54 | if (relationType == constants_1.Decorators.ONETOONE)
|
55 | fromSchema.hasOne(toSchema, { as: path, foreignKey: metaData.foreignKey });
|
56 | let relationToDictionary = {};
|
57 | relationToDictionary.metaData = metaData;
|
58 | relationToDictionary.type = relationType;
|
59 | relationToDictionary["relation"] = metaData.rel;
|
60 | relationToDictionary.fromSchema = fromSchema;
|
61 | relationToDictionary.toSchema = toSchema;
|
62 | relationToDictionary.path = path;
|
63 | this._relationCollection.push(relationToDictionary);
|
64 | }
|
65 | parseProperties(props, schemaModel) {
|
66 | let config = {};
|
67 | props.forEach(prop => {
|
68 | if (prop.indexOf('.') < 0) {
|
69 | config['attributes'] = config['attributes'] ? config['attributes'] : [];
|
70 | config['attributes'].push(prop);
|
71 | }
|
72 | else {
|
73 | let foreignKeys = prop.split('.');
|
74 | this.insertForeignKey(config, foreignKeys, schemaModel);
|
75 | }
|
76 | });
|
77 | return config;
|
78 | }
|
79 | insertForeignKey(config, foreignKeys, schemaModel) {
|
80 | let modelConfig = config;
|
81 | foreignKeys.forEach((x, i) => {
|
82 | if (foreignKeys.length - 1 == i) {
|
83 | modelConfig['attributes'] = modelConfig['attributes'] ? modelConfig['attributes'] : [];
|
84 | let relSchemas = this._relationCollection.filter(schema => (schema.relation == schemaModel.name));
|
85 | if (relSchemas.length > 0 && relSchemas[0].toSchema.primaryKeyAttribute != x) {
|
86 | modelConfig['attributes'].push(x);
|
87 | }
|
88 | }
|
89 | else {
|
90 | modelConfig['include'] = modelConfig['include'] ? modelConfig['include'] : [];
|
91 | let filterConfig = modelConfig.include.filter(p => p.as == x);
|
92 | if (!filterConfig.length) {
|
93 | let relSchemas = this._relationCollection.filter(schema => (schema.fromSchema.name == schemaModel.name) && (schema.type == constants_1.Decorators.MANYTOONE) && (schema.path == x));
|
94 | if (relSchemas.length > 0) {
|
95 | schemaModel = relSchemas[0].toSchema;
|
96 | let tempConfig = { model: relSchemas[0].toSchema, as: relSchemas[0].path, attributes: [relSchemas[0].toSchema.primaryKeyAttribute] };
|
97 | modelConfig.include.push(tempConfig);
|
98 | modelConfig = tempConfig;
|
99 | }
|
100 | }
|
101 | else {
|
102 | let relSchemas = this._relationCollection.filter(schema => (schema.fromSchema.name == schemaModel.name) && (schema.type == constants_1.Decorators.MANYTOONE) && (schema.path == x));
|
103 | if (relSchemas.length > 0) {
|
104 | schemaModel = relSchemas[0].toSchema;
|
105 | }
|
106 | modelConfig = filterConfig[0];
|
107 | }
|
108 | }
|
109 | });
|
110 | }
|
111 | getAllForeignKeyAssocationsForFindWhere(inputArr, schemaModel) {
|
112 | let parseProperties = this.parseProperties(inputArr, schemaModel);
|
113 | return parseProperties;
|
114 | }
|
115 | getAllForeignKeyAssocations(schemaModel, properties) {
|
116 | let includes = [];
|
117 | let relSchemas = this._relationCollection.filter(x => (x.fromSchema.name == schemaModel.name) && (x.type == constants_1.Decorators.MANYTOONE));
|
118 | if (relSchemas.length) {
|
119 | relSchemas.forEach(x => {
|
120 | if (!properties || !properties.length || properties.indexOf(x.path) >= 0) {
|
121 | if (x.metaData.eagerLoading) {
|
122 | let model = { model: x.toSchema, as: x.path };
|
123 | if (x.metaData.properties) {
|
124 | model['attributes'] = x.metaData.properties;
|
125 | }
|
126 | let childModel = this.getAllForeignKeyAssocations(x.toSchema, x.metaData.properties);
|
127 | if (childModel.length) {
|
128 | model['include'] = childModel;
|
129 | }
|
130 | includes.push(model);
|
131 | }
|
132 | }
|
133 | });
|
134 | }
|
135 | return includes;
|
136 | }
|
137 | getAllForeignKeyAssocationsForManyToOne(schemaModel, properties) {
|
138 | let includes = [];
|
139 | let relSchemas = this._relationCollection.filter(x => (x.fromSchema.name == schemaModel.name) && (x.type == constants_1.Decorators.MANYTOONE));
|
140 | if (relSchemas.length) {
|
141 | relSchemas.forEach(x => {
|
142 | if (!properties || !properties.length || properties.indexOf(x.path) >= 0) {
|
143 | if (x.metaData.eagerLoading) {
|
144 | let model = { model: x.toSchema, as: x.path };
|
145 | if (x.metaData.properties) {
|
146 | model['attributes'] = x.metaData.properties;
|
147 | }
|
148 | let childModel = this.getAllForeignKeyAssocationsForManyToOne(x.toSchema, x.metaData.properties);
|
149 | if (childModel.length) {
|
150 | model['include'] = childModel;
|
151 | }
|
152 | includes.push(model);
|
153 | }
|
154 | }
|
155 | });
|
156 | }
|
157 | return includes;
|
158 | }
|
159 | getAllForeignKeyAssocationsOneToMany(type, schemaModel, properties) {
|
160 | let includes = [];
|
161 | let relSchemas = this._relationCollection.filter(x => (x.fromSchema.name == schemaModel.name) && (x.type == type));
|
162 | if (relSchemas.length) {
|
163 | relSchemas.forEach(x => {
|
164 | if (!properties || !properties.length || properties.indexOf(x.path) >= 0) {
|
165 | if (x.metaData.eagerLoading) {
|
166 | let model = { model: x.toSchema, as: x.path };
|
167 | if (x.metaData.properties) {
|
168 | model['attributes'] = x.metaData.properties;
|
169 | }
|
170 | let childModel = this.getAllForeignKeyAssocationsOneToMany(type, x.toSchema, x.metaData.properties);
|
171 | if (childModel.length) {
|
172 | model['include'] = childModel;
|
173 | }
|
174 | includes.push(model);
|
175 | }
|
176 | }
|
177 | });
|
178 | }
|
179 | return includes;
|
180 | }
|
181 | getModel(repoPath, dynamicName) {
|
182 | try {
|
183 | var schemaNamefromPathRepomap = model_entity_1.pathRepoMap[repoPath].schemaName;
|
184 | return this._schemaCollection[schemaNamefromPathRepomap];
|
185 | }
|
186 | catch (e) {
|
187 | throw e;
|
188 | }
|
189 | }
|
190 | appendTransaction(options) {
|
191 | let trans = principalContext_1.PrincipalContext.get(constantKeys_1.ConstantKeys.transaction);
|
192 | if (trans) {
|
193 | options['transaction'] = trans;
|
194 | }
|
195 | return options;
|
196 | }
|
197 | bulkPost(repoPath, objArr, batchSize) {
|
198 | let options = { individualHooks: true };
|
199 | options = this.appendTransaction(options);
|
200 | return this.getModel(repoPath).bulkCreate(objArr, options).then(result => {
|
201 | return result.map(x => x.dataValues);
|
202 | });
|
203 | }
|
204 | bulkPutMany(repoPath, objIds, obj) {
|
205 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
206 | let cond = {};
|
207 | cond[primaryKey] = objIds;
|
208 | let options = { where: cond };
|
209 | options = this.appendTransaction(options);
|
210 | return this.getModel(repoPath).update(obj, options).then(result => {
|
211 | return this.findMany(repoPath, objIds, false);
|
212 | });
|
213 | }
|
214 | bulkDel(repoPath, objArr) {
|
215 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
216 | let cond = {};
|
217 | if (utils_1.isJSON(objArr[0])) {
|
218 | cond[primaryKey] = objArr.map(x => x[primaryKey]);
|
219 | }
|
220 | else {
|
221 | cond[primaryKey] = objArr;
|
222 | }
|
223 | let options = { where: cond };
|
224 | options = this.appendTransaction(options);
|
225 | return this.getModel(repoPath).destroy(options).then(result => {
|
226 | return { success: result };
|
227 | });
|
228 | }
|
229 | bulkPut(repoPath, objArr, batchSize) {
|
230 | let asyncalls = [];
|
231 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
232 | objArr.forEach(obj => {
|
233 | let cond = {};
|
234 | cond[primaryKey] = obj[primaryKey];
|
235 | let options = { where: cond };
|
236 | options = this.appendTransaction(options);
|
237 | asyncalls.push(this.getModel(repoPath).update(obj, options));
|
238 | });
|
239 | return Q.allSettled(asyncalls).then(result => {
|
240 | return this.findMany(repoPath, objArr.map(x => x[primaryKey]), false);
|
241 | });
|
242 | }
|
243 | bulkPatch(repoPath, objArr) {
|
244 | return this.bulkPut(repoPath, objArr);
|
245 | }
|
246 | findAll(repoPath) {
|
247 | return this.getModel(repoPath).findAll({ raw: true }).then(result => {
|
248 | if (!result)
|
249 | return null;
|
250 |
|
251 | return result;
|
252 | });
|
253 | }
|
254 | findWhere(repoPath, query, selectedFields, queryOptions, toLoadChilds) {
|
255 | let schemaModel = this.getModel(repoPath);
|
256 | let cond = {};
|
257 | if (selectedFields && selectedFields.length > 0) {
|
258 | cond = this.getAllForeignKeyAssocationsForFindWhere(selectedFields, schemaModel);
|
259 | }
|
260 | else {
|
261 | cond['include'] = this.getAllForeignKeyAssocations(schemaModel, []);
|
262 | }
|
263 | cond["where"] = query;
|
264 | if (queryOptions) {
|
265 | if (queryOptions.skip) {
|
266 | cond['offset'] = parseInt(queryOptions.skip.toString());
|
267 | }
|
268 | if (queryOptions.limit) {
|
269 | cond['limit'] = parseInt(queryOptions.limit.toString());
|
270 | }
|
271 | if (queryOptions.sort) {
|
272 | cond['order'] = queryOptions.sort;
|
273 | }
|
274 | }
|
275 | return schemaModel.findAll(cond).then(result => {
|
276 | if (!result)
|
277 | return null;
|
278 | return result.map(x => x.dataValues);
|
279 | });
|
280 | }
|
281 |
|
282 |
|
283 | countWhere(repoPath, query) {
|
284 | return this.getModel(repoPath).findAndCountAll({ where: query }).then(result => {
|
285 | return result;
|
286 | });
|
287 | }
|
288 |
|
289 |
|
290 | distinctWhere(repoPath, query) {
|
291 | if (!query) {
|
292 | query = {};
|
293 | }
|
294 | query.distinct = true;
|
295 | return this.getModel(repoPath).findAndCountAll(query).then(result => {
|
296 | return result;
|
297 | });
|
298 | }
|
299 | findOne(repoPath, id, donotLoadChilds) {
|
300 | let schemaModel = this.getModel(repoPath);
|
301 | let primaryKey = schemaModel.primaryKeyAttribute;
|
302 | var cond = {};
|
303 | cond[primaryKey] = id;
|
304 | let include1 = donotLoadChilds ? [] : this.getAllForeignKeyAssocationsForManyToOne(schemaModel, null);
|
305 | let include2 = donotLoadChilds ? [] : this.getAllForeignKeyAssocationsOneToMany(constants_1.Decorators.ONETOMANY, schemaModel, null);
|
306 | let include3 = donotLoadChilds ? [] : this.getAllForeignKeyAssocationsOneToMany(constants_1.Decorators.ONETOONE, schemaModel, null);
|
307 | let include = include1.concat(include2).concat(include3);
|
308 | console.log('%%%%%%%%%%%%%%%%%%%%' + include);
|
309 | return schemaModel.find({ include: include, where: cond }).then(result => {
|
310 | return result.dataValues;
|
311 | })
|
312 | .catch(err => {
|
313 | console.log('####' + err);
|
314 | });
|
315 | }
|
316 | findByField(repoPath, fieldName, value) {
|
317 | return this.getModel(repoPath).find({ where: { fieldName: value } });
|
318 | }
|
319 | findMany(repoPath, ids, toLoadEmbeddedChilds) {
|
320 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
321 | let cond = {};
|
322 | cond[primaryKey] = ids;
|
323 | return this.findWhere(repoPath, cond, [], null, toLoadEmbeddedChilds);
|
324 | }
|
325 | findChild(repoPath, id, prop) {
|
326 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
327 | let cond = {};
|
328 | cond[primaryKey] = id;
|
329 | return this.getModel(repoPath).find({
|
330 | where: cond,
|
331 | include: [
|
332 | { model: this.getModel(prop), as: prop }
|
333 | ]
|
334 | }).then(function (entity) {
|
335 | return entity[prop];
|
336 | });
|
337 | }
|
338 | |
339 |
|
340 |
|
341 |
|
342 |
|
343 | post(repoPath, obj) {
|
344 | let options = {};
|
345 | options = this.appendTransaction(options);
|
346 | return this.getModel(repoPath).create(obj, options);
|
347 | }
|
348 | put(repoPath, id, obj) {
|
349 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
350 | let cond = {};
|
351 | cond[primaryKey] = id;
|
352 | let options = { where: cond };
|
353 | options = this.appendTransaction(options);
|
354 | return this.getModel(repoPath).update(obj, options).then(result => {
|
355 | return this.findOne(repoPath, id);
|
356 | });
|
357 | }
|
358 | del(repoPath, id) {
|
359 | let primaryKey = this.getModel(repoPath).primaryKeyAttribute;
|
360 | let cond = {};
|
361 | cond[primaryKey] = id;
|
362 | let options = { where: cond };
|
363 | options = this.appendTransaction(options);
|
364 | return this.getModel(repoPath).destroy(options).then(result => {
|
365 | return { success: result };
|
366 | });
|
367 | }
|
368 | patch(repoPath, id, obj) {
|
369 | return this.put(repoPath, id, obj);
|
370 | }
|
371 | getSortCondition(val) {
|
372 | return JSON.parse(val);
|
373 | }
|
374 | getLikeCondition(val) {
|
375 | val = queryString.parse('key=' + val)['key'];
|
376 | return {
|
377 | [this.sequelize.Op.like]: '%' + val + '%'
|
378 | };
|
379 | }
|
380 | getStartsWithCondition(val) {
|
381 | val = queryString.parse('key=' + val)['key'];
|
382 | return {
|
383 | [this.sequelize.Op.like]: val + '%'
|
384 | };
|
385 | }
|
386 | getPrimaryKey(repoPath) {
|
387 | return this.getModel(repoPath).primaryKeyAttribute;
|
388 | }
|
389 | getAssociationForSchema(model, schema) {
|
390 | Enumerable.from(this._relationCollection)
|
391 | .where(relationSchema => relationSchema.fromSchema == schema).forEach(relation1 => {
|
392 | model.dataValues[relation1.path] = model[relation1.toSchema.name + "s"];
|
393 | });
|
394 | }
|
395 | }
|
396 | exports.sequelizeService = new SequelizeService();
|
397 |
|
398 |
|
399 |
|