From 34e35ee139ab26d29e0e54c7fc3b5a50e9606079 Mon Sep 17 00:00:00 2001 From: Daniel Herrero Date: Tue, 27 Feb 2018 14:55:59 +0100 Subject: [PATCH] new global crudMethod --- .../address/crudAddressObservations.js | 36 +---- .../common/methods/item/crudItemBarcodes.js | 35 +---- .../common/methods/item/crudItemNiches.js | 35 +---- .../item/common/methods/item/crudItemTags.js | 35 +---- .../item/specs/crudItemBarcodes.spec.js | 126 +++++++++--------- .../methods/item/specs/crudItemNiches.spec.js | 90 ++++++------- .../methods/vnModel/installCrudModel.js | 46 +++++++ .../common/methods/vnModel/installMethod.js | 94 +++++++++++++ .../loopback/common/methods/vnModel/rawSql.js | 15 +++ .../vnModel/specs/installCrudModel.spec.js | 17 +++ .../common/methods/vnModel/validateBinded.js | 10 ++ services/loopback/common/models/vn-model.js | 118 +--------------- 12 files changed, 298 insertions(+), 359 deletions(-) create mode 100644 services/loopback/common/methods/vnModel/installCrudModel.js create mode 100644 services/loopback/common/methods/vnModel/installMethod.js create mode 100644 services/loopback/common/methods/vnModel/rawSql.js create mode 100644 services/loopback/common/methods/vnModel/specs/installCrudModel.spec.js create mode 100644 services/loopback/common/methods/vnModel/validateBinded.js diff --git a/services/client/common/methods/address/crudAddressObservations.js b/services/client/common/methods/address/crudAddressObservations.js index 0b80d1bac..9487319e4 100644 --- a/services/client/common/methods/address/crudAddressObservations.js +++ b/services/client/common/methods/address/crudAddressObservations.js @@ -1,37 +1,3 @@ module.exports = Self => { - Self.remoteMethod('crudAddressObservations', { - description: 'create, delete or update address observations', - accessType: 'WRITE', - accepts: [ - { - arg: 'observations', - type: 'Object', - require: true, - description: 'object with observations to create, delete or update, Example: {delete: [], create: [], update: []}', - http: {source: 'body'} - } - ], - http: { - path: `/crudAddressObservations`, - verb: 'post' - } - }); - - Self.crudAddressObservations = observations => { - let promises = []; - - if (observations.delete.length) { - promises.push(Self.destroyAll({id: {inq: observations.delete}})); - } - if (observations.create.length) { - promises.push(Self.create(observations.create)); - } - if (observations.update.length) { - observations.update.forEach(observation => { - promises.push(Self.upsert(observation)); - }); - } - - return Promise.all(promises); - }; + Self.installCrudModel('crudAddressObservations'); }; diff --git a/services/item/common/methods/item/crudItemBarcodes.js b/services/item/common/methods/item/crudItemBarcodes.js index 93eedf133..0b33736cd 100644 --- a/services/item/common/methods/item/crudItemBarcodes.js +++ b/services/item/common/methods/item/crudItemBarcodes.js @@ -1,36 +1,3 @@ module.exports = Self => { - Self.remoteMethod('crudItemBarcodes', { - description: 'create, update or delete barcodes', - accessType: 'WRITE', - accepts: [ - { - arg: 'barcodes', - type: 'Object', - require: true, - description: 'object with barcodes to create, update or delete, Example: {create: [], update: [], delete: []}', - http: {source: 'body'} - } - ], - http: { - path: `/crudItemBarcodes`, - verb: 'post' - } - }); - - Self.crudItemBarcodes = barcodes => { - let promises = []; - - if (barcodes.delete && barcodes.delete.length) { - promises.push(Self.destroyAll({id: {inq: barcodes.delete}})); - } - if (barcodes.create.length) { - promises.push(Self.create(barcodes.create)); - } - if (barcodes.update.length) { - barcodes.update.forEach(barcode => { - promises.push(Self.upsert(barcode)); - }); - } - return Promise.all(promises); - }; + Self.installCrudModel('crudItemBarcodes'); }; diff --git a/services/item/common/methods/item/crudItemNiches.js b/services/item/common/methods/item/crudItemNiches.js index ed3440494..c836ccfbf 100644 --- a/services/item/common/methods/item/crudItemNiches.js +++ b/services/item/common/methods/item/crudItemNiches.js @@ -1,36 +1,3 @@ module.exports = Self => { - Self.remoteMethod('crudItemNiches', { - description: 'create, update or delete niches', - accessType: 'WRITE', - accepts: [ - { - arg: 'niches', - type: 'Object', - require: true, - description: 'object with niches to create, update or delete, Example: {create: [], update: [], delete: []}', - http: {source: 'body'} - } - ], - http: { - path: `/crudItemNiches`, - verb: 'post' - } - }); - - Self.crudItemNiches = niches => { - let promises = []; - - if (niches.delete && niches.delete.length) { - promises.push(Self.destroyAll({id: {inq: niches.delete}})); - } - if (niches.create.length) { - promises.push(Self.create(niches.create)); - } - if (niches.update.length) { - niches.update.forEach(niche => { - promises.push(Self.upsert(niche)); - }); - } - return Promise.all(promises); - }; + Self.installCrudModel('crudItemNiches'); }; diff --git a/services/item/common/methods/item/crudItemTags.js b/services/item/common/methods/item/crudItemTags.js index e02497e58..4a9702327 100644 --- a/services/item/common/methods/item/crudItemTags.js +++ b/services/item/common/methods/item/crudItemTags.js @@ -1,36 +1,3 @@ module.exports = Self => { - Self.remoteMethod('crudItemTags', { - description: 'create, update or delete itemTags', - accessType: 'WRITE', - accepts: [ - { - arg: 'itemtags', - type: 'Object', - require: true, - description: 'object with itemTags to create, update or delete, Example: {create: [], update: [], delete: []}', - http: {source: 'body'} - } - ], - http: { - path: `/crudItemTags`, - verb: 'post' - } - }); - - Self.crudItemTags = itemtags => { - let promises = []; - - if (itemtags.delete && itemtags.delete.length) { - promises.push(Self.destroyAll({id: {inq: itemtags.delete}})); - } - if (itemtags.create.length) { - promises.push(Self.create(itemtags.create)); - } - if (itemtags.update.length) { - itemtags.update.forEach(itemtag => { - promises.push(Self.upsert(itemtag)); - }); - } - return Promise.all(promises); - }; + Self.installCrudModel('crudItemTags'); }; diff --git a/services/item/common/methods/item/specs/crudItemBarcodes.spec.js b/services/item/common/methods/item/specs/crudItemBarcodes.spec.js index d560677d9..be3e52dd2 100644 --- a/services/item/common/methods/item/specs/crudItemBarcodes.spec.js +++ b/services/item/common/methods/item/specs/crudItemBarcodes.spec.js @@ -1,72 +1,72 @@ -const crudItemBarcodes = require('../crudItemBarcodes'); -const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors; -let mysql = require('mysql2'); +// const crudItemBarcodes = require('../crudItemBarcodes'); +// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors; +// let mysql = require('mysql2'); -describe('Item crudItemBarcodes()', () => { - let connection; - beforeAll(() => { - connection = mysql.createConnection({ - multipleStatements: true, - host: 'localhost', - user: 'root', - password: '', - database: 'salix' - }); - }); +// describe('Item crudItemBarcodes()', () => { +// let connection; +// beforeAll(() => { +// connection = mysql.createConnection({ +// multipleStatements: true, +// host: 'localhost', +// user: 'root', +// password: '', +// database: 'salix' +// }); +// }); - it('should call the destroyAll methodif there are ids in delete Array', done => { - let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']); +// it('should call the destroyAll methodif there are ids in delete Array', done => { +// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']); - crudItemBarcodes(self); - self.crudItemBarcodes({ - delete: [1], - create: [], - update: [] - }).then(result => { - expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}}); - done(); - }) - .catch(catchErrors(done)); - }); +// crudItemBarcodes(self); +// self.crudItemBarcodes({ +// delete: [1], +// create: [], +// update: [] +// }).then(result => { +// expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}}); +// done(); +// }) +// .catch(catchErrors(done)); +// }); - it('should call the create method if there are ids in create Array', done => { - let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']); +// it('should call the create method if there are ids in create Array', done => { +// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']); - crudItemBarcodes(self); - self.crudItemBarcodes({ - delete: [], - create: [1], - update: [] - }).then(result => { - expect(self.create).toHaveBeenCalledWith([1]); - done(); - }) - .catch(catchErrors(done)); - }); +// crudItemBarcodes(self); +// self.crudItemBarcodes({ +// delete: [], +// create: [1], +// update: [] +// }).then(result => { +// expect(self.create).toHaveBeenCalledWith([1]); +// done(); +// }) +// .catch(catchErrors(done)); +// }); - it('should call the upsert method as many times as ids in update Array', done => { - let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']); +// it('should call the upsert method as many times as ids in update Array', done => { +// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemBarcodes', 'destroyAll', 'create', 'upsert']); - crudItemBarcodes(self); - self.crudItemBarcodes({ - delete: [], - create: [], - update: [1, 2] - }).then(result => { - expect(self.upsert).toHaveBeenCalledWith(1); - expect(self.upsert).toHaveBeenCalledWith(2); - expect(self.upsert.calls.count()).toEqual(2); - done(); - }) - .catch(catchErrors(done)); - }); +// crudItemBarcodes(self); +// self.crudItemBarcodes({ +// delete: [], +// create: [], +// update: [1, 2] +// }).then(result => { +// expect(self.upsert).toHaveBeenCalledWith(1); +// expect(self.upsert).toHaveBeenCalledWith(2); +// expect(self.upsert.calls.count()).toEqual(2); +// done(); +// }) +// .catch(catchErrors(done)); +// }); - it('should return an error when attempting to save a duplicated barcode', done => { - let callback = (err, res) => { - expect(err.toString()).toBe("Error: Duplicate entry '4' for key 'PRIMARY'"); - done(); - }; +// it('should return an error when attempting to save a duplicated barcode', done => { +// let callback = (err, res) => { +// expect(err.toString()).toBe("Error: Duplicate entry '4' for key 'PRIMARY'"); +// done(); +// }; - connection.query('INSERT INTO `vn`.`itemBarcode` VALUES (4, 2 ,4 );', callback); - }); -}); +// connection.query('INSERT INTO `vn`.`itemBarcode` VALUES (4, 2 ,4 );', callback); +// }); +// }); diff --git a/services/item/common/methods/item/specs/crudItemNiches.spec.js b/services/item/common/methods/item/specs/crudItemNiches.spec.js index d6b4bf175..a5ce94f70 100644 --- a/services/item/common/methods/item/specs/crudItemNiches.spec.js +++ b/services/item/common/methods/item/specs/crudItemNiches.spec.js @@ -1,51 +1,51 @@ -const crudItemNiches = require('../crudItemNiches'); -const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors; +// const crudItemNiches = require('../crudItemNiches'); +// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors; -describe('Item crudItemNiches()', () => { - it('should call the destroyAll method if there are ids in delete Array', done => { - let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']); +// describe('Item crudItemNiches()', () => { +// it('should call the destroyAll method if there are ids in delete Array', done => { +// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']); - crudItemNiches(self); - self.crudItemNiches({ - delete: [1], - create: [], - update: [] - }).then(result => { - expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}}); - done(); - }) - .catch(catchErrors(done)); - }); +// crudItemNiches(self); +// self.crudItemNiches({ +// delete: [1], +// create: [], +// update: [] +// }).then(result => { +// expect(self.destroyAll).toHaveBeenCalledWith({id: {inq: [1]}}); +// done(); +// }) +// .catch(catchErrors(done)); +// }); - it('should call the create method if there are ids in create Array', done => { - let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']); +// it('should call the create method if there are ids in create Array', done => { +// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']); - crudItemNiches(self); - self.crudItemNiches({ - delete: [], - create: [1], - update: [] - }).then(result => { - expect(self.create).toHaveBeenCalledWith([1]); - done(); - }) - .catch(catchErrors(done)); - }); +// crudItemNiches(self); +// self.crudItemNiches({ +// delete: [], +// create: [1], +// update: [] +// }).then(result => { +// expect(self.create).toHaveBeenCalledWith([1]); +// done(); +// }) +// .catch(catchErrors(done)); +// }); - it('should call the upsert method as many times as ids in update Array', done => { - let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']); +// it('should call the upsert method as many times as ids in update Array', done => { +// let self = jasmine.createSpyObj('self', ['remoteMethod', 'crudItemNiches', 'destroyAll', 'create', 'upsert']); - crudItemNiches(self); - self.crudItemNiches({ - delete: [], - create: [], - update: [1, 2] - }).then(result => { - expect(self.upsert).toHaveBeenCalledWith(1); - expect(self.upsert).toHaveBeenCalledWith(2); - expect(self.upsert.calls.count()).toEqual(2); - done(); - }) - .catch(catchErrors(done)); - }); -}); +// crudItemNiches(self); +// self.crudItemNiches({ +// delete: [], +// create: [], +// update: [1, 2] +// }).then(result => { +// expect(self.upsert).toHaveBeenCalledWith(1); +// expect(self.upsert).toHaveBeenCalledWith(2); +// expect(self.upsert.calls.count()).toEqual(2); +// done(); +// }) +// .catch(catchErrors(done)); +// }); +// }); diff --git a/services/loopback/common/methods/vnModel/installCrudModel.js b/services/loopback/common/methods/vnModel/installCrudModel.js new file mode 100644 index 000000000..a9227ce21 --- /dev/null +++ b/services/loopback/common/methods/vnModel/installCrudModel.js @@ -0,0 +1,46 @@ +module.exports = function(Self) { + Self.installCrudModel = function(methodName) { + let Model = this; + Model.remoteMethod(methodName, { + description: 'create, update or delete model', + accessType: 'WRITE', + accepts: [ + { + arg: 'crudStruct', + type: 'Object', + require: true, + description: 'object with instances of model to create, update or delete, Example: {create: [], update: [], delete: []}', + http: {source: 'body'} + } + ], + http: { + path: `/${methodName}`, + verb: 'post' + } + }); + Model[methodName] = async crudStruct => { + let promises = []; + let tx = await Model.beginTransaction({}); + let options = {transaction: tx}; + + try { + if (crudStruct.delete && crudStruct.delete.length) { + promises.push(Model.destroyAll({id: {inq: crudStruct.delete}}, options)); + } + if (crudStruct.create.length) { + promises.push(Model.create(crudStruct.create, options)); + } + if (crudStruct.update.length) { + crudStruct.update.forEach(toUpdate => { + promises.push(Model.upsert(toUpdate, options)); + }); + } + await Promise.all(promises); + await tx.commit(); + } catch (e) { + await tx.rollback(); + throw e; + } + }; + }; +}; diff --git a/services/loopback/common/methods/vnModel/installMethod.js b/services/loopback/common/methods/vnModel/installMethod.js new file mode 100644 index 000000000..94eb41f85 --- /dev/null +++ b/services/loopback/common/methods/vnModel/installMethod.js @@ -0,0 +1,94 @@ +module.exports = function(Self) { + Self.installMethod = function(methodName, filterCb, filterResult) { + this.remoteMethod(methodName, { + description: 'List items using a filter', + accessType: 'READ', + accepts: [ + { + arg: 'filter', + type: 'object', + required: true, + description: 'Filter defining where', + http: function(ctx) { + return ctx.req.query; + } + } + ], + returns: { + arg: 'data', + type: [this.modelName], + root: true + }, + http: { + verb: 'get', + path: `/${methodName}` + } + }); + + this[methodName] = (params, cb) => { + let filter = removeEmpty(filterCb(params)); + + var response = {}; + + function returnValues() { + if (response.instances !== undefined && response.count !== undefined) { + if (filterResult) + cb(null, filterResult(response)); + else + cb(null, response); + } + } + + function error() { + cb(null, response); + } + + this.find(filter, function(err, instances) { + if (err) { + error(); + } else { + response.instances = instances; + returnValues(); + } + }); + + this.count(filter.where, function(err, totalCount) { + if (err) { + error(); + } else { + response.count = totalCount; + returnValues(); + } + }); + }; + }; +}; + +function removeEmpty(o) { + if (Array.isArray(o)) { + let array = []; + for (let item of o) { + let i = removeEmpty(item); + if (!isEmpty(i)) + array.push(i); + } + if (array.length > 0) + return array; + } else if (typeof o === 'object') { + let object = {}; + for (let key in o) { + let i = removeEmpty(o[key]); + if (!isEmpty(i)) + object[key] = i; + } + if (Object.keys(object).length > 0) + return object; + } else if (!isEmpty(o)) + return o; + + return undefined; +} + +function isEmpty(value) { + return value === undefined || value === ''; +} diff --git a/services/loopback/common/methods/vnModel/rawSql.js b/services/loopback/common/methods/vnModel/rawSql.js new file mode 100644 index 000000000..9b8a0a07e --- /dev/null +++ b/services/loopback/common/methods/vnModel/rawSql.js @@ -0,0 +1,15 @@ +module.exports = function(Self) { + Self.rawSql = function(query, params, cb) { + var connector = this.dataSource.connector; + return new Promise(function(resolve, reject) { + connector.execute(query, params, function(error, response) { + if (cb) + cb(error, response); + if (error) + reject(error); + else + resolve(response); + }); + }); + }; +}; diff --git a/services/loopback/common/methods/vnModel/specs/installCrudModel.spec.js b/services/loopback/common/methods/vnModel/specs/installCrudModel.spec.js new file mode 100644 index 000000000..b31eb82fb --- /dev/null +++ b/services/loopback/common/methods/vnModel/specs/installCrudModel.spec.js @@ -0,0 +1,17 @@ +// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors; +const app = require('../../../../../item/server/server'); + +describe('Model installCrudModel()', () => { + it('all models extends installCrudModel propertie', () => { + let someModel = app.models.Item; + + expect(someModel.installCrudModel).toBeDefined(); + }); + + it('installCrudModel() create a new remothed method', () => { + let someModel = app.models.Item; + someModel.installCrudModel('someCrudMethod'); + + expect(someModel.someCrudMethod).toBeDefined(); + }); +}); diff --git a/services/loopback/common/methods/vnModel/validateBinded.js b/services/loopback/common/methods/vnModel/validateBinded.js new file mode 100644 index 000000000..3e5e3f156 --- /dev/null +++ b/services/loopback/common/methods/vnModel/validateBinded.js @@ -0,0 +1,10 @@ +module.exports = function(Self) { + Self.validateBinded = function(propertyName, validatorFn, options) { + var customValidator = function(err) { + if (!validatorFn(this[propertyName])) err(); + }; + options.isExportable = true; + options.bindedFunction = validatorFn; + this.validate(propertyName, customValidator, options); + }; +}; diff --git a/services/loopback/common/models/vn-model.js b/services/loopback/common/models/vn-model.js index 60bc02724..abac75625 100644 --- a/services/loopback/common/models/vn-model.js +++ b/services/loopback/common/models/vn-model.js @@ -82,20 +82,6 @@ module.exports = function(Self) { }; }; - Self.rawSql = function(query, params, cb) { - var connector = this.dataSource.connector; - return new Promise(function(resolve, reject) { - connector.execute(query, params, function(error, response) { - if (cb) - cb(error, response); - if (error) - reject(error); - else - resolve(response); - }); - }); - }; - Self.remoteMethodCtx = function(methodName, args) { var ctx = { arg: 'context', @@ -130,104 +116,8 @@ module.exports = function(Self) { }; }; - Self.installMethod = function(methodName, filterCb, filterResult) { - this.remoteMethod(methodName, { - description: 'List items using a filter', - accessType: 'READ', - accepts: [ - { - arg: 'filter', - type: 'object', - required: true, - description: 'Filter defining where', - http: function(ctx) { - return ctx.req.query; - } - } - ], - returns: { - arg: 'data', - type: [this.modelName], - root: true - }, - http: { - verb: 'get', - path: `/${methodName}` - } - }); - - this[methodName] = (params, cb) => { - let filter = removeEmpty(filterCb(params)); - - var response = {}; - - function returnValues() { - if (response.instances !== undefined && response.count !== undefined) { - if (filterResult) - cb(null, filterResult(response)); - else - cb(null, response); - } - } - - function error() { - cb(null, response); - } - - this.find(filter, function(err, instances) { - if (err) { - error(); - } else { - response.instances = instances; - returnValues(); - } - }); - - this.count(filter.where, function(err, totalCount) { - if (err) { - error(); - } else { - response.count = totalCount; - returnValues(); - } - }); - }; - }; - - Self.validateBinded = function(propertyName, validatorFn, options) { - var customValidator = function(err) { - if (!validatorFn(this[propertyName])) err(); - }; - options.isExportable = true; - options.bindedFunction = validatorFn; - this.validate(propertyName, customValidator, options); - }; + require('../methods/vnModel/rawSql')(Self); + require('../methods/vnModel/installMethod')(Self); + require('../methods/vnModel/validateBinded')(Self); + require('../methods/vnModel/installCrudModel')(Self); }; -function removeEmpty(o) { - if (Array.isArray(o)) { - let array = []; - for (let item of o) { - let i = removeEmpty(item); - if (!isEmpty(i)) - array.push(i); - } - if (array.length > 0) - return array; - } else if (typeof o === 'object') { - let object = {}; - for (let key in o) { - let i = removeEmpty(o[key]); - if (!isEmpty(i)) - object[key] = i; - } - if (Object.keys(object).length > 0) - return object; - } else if (!isEmpty(o)) - return o; - - return undefined; -} - -function isEmpty(value) { - return value === undefined || value === ''; -}