From baeb76e91141867ff099b96c2790fcb2f5331dc3 Mon Sep 17 00:00:00 2001 From: Agnes Lin Date: Mon, 27 Jan 2020 13:25:31 -0500 Subject: [PATCH] allows diff db cols naming conventions 4 discover --- lib/datasource.js | 51 +++++++++++++++++++++++++++++------------- package.json | 1 + test/discovery.test.js | 15 ++++++++++++- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/lib/datasource.js b/lib/datasource.js index f82a3e5a..1d2fc20a 100644 --- a/lib/datasource.js +++ b/lib/datasource.js @@ -28,6 +28,8 @@ const g = require('strong-globalize')(); const juggler = require('..'); const deprecated = require('depd')('loopback-datasource-juggler'); const Transaction = require('loopback-connector').Transaction; +const pascalCase = require('change-case').pascalCase; +const camelCase = require('change-case').camelCase; if (process.env.DEBUG === 'loopback') { // For back-compatibility @@ -1450,17 +1452,22 @@ function capitalize(str) { return str.charAt(0).toUpperCase() + ((str.length > 1) ? str.slice(1).toLowerCase() : ''); } -function fromDBName(dbName, camelCase) { - if (!dbName) { - return dbName; +/** + * Renames db column names with different naming conventions: + * camelCase for property names as it's LB default naming convention for properties, + * or keep the name the same if needed. + * + * @param {*} name name defined in database + * @param {*} caseFunction optional. A function to convert the name into different case. + */ +function fromDBName(name, caseFunction) { + if (!name) { + return name; } - const parts = dbName.split(/-|_/); - parts[0] = camelCase ? parts[0].toLowerCase() : capitalize(parts[0]); - - for (let i = 1; i < parts.length; i++) { - parts[i] = capitalize(parts[i]); + if (typeof caseFunction === 'function') { + return caseFunction(name); } - return parts.join(''); + return name; } /** @@ -1567,13 +1574,14 @@ DataSource.prototype.discoverSchemas = function(tableName, options, cb) { cb = options; options = {}; } - cb = cb || utils.createPromiseCallback(); const self = this; const dbType = this.connector.name; let nameMapper; + const disableCamelCase = !!options.disableCamelCase; + if (options.nameMapper === null) { // No mapping nameMapper = function(type, name) { @@ -1586,11 +1594,19 @@ DataSource.prototype.discoverSchemas = function(tableName, options, cb) { // Default name mapper nameMapper = function mapName(type, name) { if (type === 'table' || type === 'model') { - return fromDBName(name, false); + return fromDBName(name, pascalCase); } else if (type == 'fk') { - return fromDBName(name + 'Rel', true); + if (disableCamelCase) { + return fromDBName(name + 'Rel'); + } else { + return fromDBName(name + 'Rel', camelCase); + } } else { - return fromDBName(name, true); + if (disableCamelCase) { + return fromDBName(name); + } else { + return fromDBName(name, camelCase); + } } }; } @@ -1770,12 +1786,17 @@ DataSource.prototype.discoverSchemasSync = function(modelName, options) { if (!columns || columns.length === 0) { return []; } + const disableCamelCase = !!options.disableCamelCase; const nameMapper = options.nameMapper || function mapName(type, name) { if (type === 'table' || type === 'model') { - return fromDBName(name, false); + return fromDBName(name, pascalCase); } else { - return fromDBName(name, true); + if (disableCamelCase) { + return fromDBName(name); + } else { + return fromDBName(name, camelCase); + } } }; diff --git a/package.json b/package.json index 3e40fdbc..1cd7e710 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ }, "dependencies": { "async": "^3.1.0", + "change-case": "^4.1.1", "debug": "^4.1.0", "depd": "^2.0.0", "inflection": "^1.6.0", diff --git a/test/discovery.test.js b/test/discovery.test.js index 42429170..c84ee839 100644 --- a/test/discovery.test.js +++ b/test/discovery.test.js @@ -73,7 +73,7 @@ describe('Memory connector with mocked discovery', function() { }; }); - it('should convert table/column names to camel cases', function(done) { + it('should convert table names to pascal cases and column names to camel case', function(done) { ds.discoverSchemas('INVENTORY', {}, function(err, schemas) { if (err) return done(err); schemas.should.have.property('STRONGLOOP.INVENTORY'); @@ -86,6 +86,19 @@ describe('Memory connector with mocked discovery', function() { }); }); + it('should keep the column names the same as database', function(done) { + ds.discoverSchemas('INVENTORY', {disableCamelCase: true}, function(err, schemas) { + if (err) return done(err); + schemas.should.have.property('STRONGLOOP.INVENTORY'); + const s = schemas['STRONGLOOP.INVENTORY']; + s.name.should.be.eql('Inventory'); + Object.keys(s.properties).should.be.eql( + ['PRODUCT_ID', 'LOCATION_ID', 'AVAILABLE', 'TOTAL'], + ); + done(); + }); + }); + it('should convert table/column names with custom mapper', function(done) { ds.discoverSchemas('INVENTORY', { nameMapper: function(type, name) {