Skip to content

Commit

Permalink
Merge pull request #1819 from strongloop/discover-naming
Browse files Browse the repository at this point in the history
feat: allows different naming conventions for db  columns for discover
  • Loading branch information
agnes512 authored Jan 29, 2020
2 parents 3a08b9d + baeb76e commit f4ec02b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 16 deletions.
51 changes: 36 additions & 15 deletions lib/datasource.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
}
};
}
Expand Down Expand Up @@ -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);
}
}
};

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
15 changes: 14 additions & 1 deletion test/discovery.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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) {
Expand Down

0 comments on commit f4ec02b

Please sign in to comment.