From 44083e43c1000055b8cabd2408ab1446659014f1 Mon Sep 17 00:00:00 2001 From: ssh24 Date: Tue, 23 May 2017 10:43:57 -0400 Subject: [PATCH] Allow explicit data types Override columnDataType function Add test cases Apply feedback Use date type as explicit datatype --- lib/migration.js | 31 +++++++++++++- package.json | 1 + test/datatypes.test.js | 95 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/lib/migration.js b/lib/migration.js index ce121ae..c88ab0d 100644 --- a/lib/migration.js +++ b/lib/migration.js @@ -702,6 +702,33 @@ function mixinMigration(MySQL, mysql) { return line; }; + // override this function from base connector to allow mysql connector to + // accept dataPrecision and dataScale as column specific properties + MySQL.prototype.columnDataType = function(model, property) { + var columnMetadata = this.columnMetadata(model, property); + var colType = columnMetadata && columnMetadata.dataType; + if (colType) { + colType = colType.toUpperCase(); + } + var prop = this.getModelDefinition(model).properties[property]; + if (!prop) { + return null; + } + var colLength = columnMetadata && columnMetadata.dataLength || prop.length || prop.limit; + var colPrecision = columnMetadata && columnMetadata.dataPrecision; + var colScale = columnMetadata && columnMetadata.dataScale; + // info on setting column specific properties + // i.e dataLength, dataPrecision, dataScale + // https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html + if (colType) { + if (colLength) return colType + '(' + colLength + ')'; + if (colPrecision && colScale) return colType + '(' + colPrecision + ',' + colScale + ')'; + if (colPrecision) return colType + '(' + colPrecision + ')'; + return colType; + } + return this.buildColumnType(prop); + }; + MySQL.prototype.buildColumnType = function buildColumnType(propertyDefinition) { var dt = ''; var p = propertyDefinition; @@ -743,7 +770,9 @@ function mixinMigration(MySQL, mysql) { function columnType(p, defaultType) { var dt = defaultType; - if (p.dataType) { + if (p.mysql && p.mysql.dataType) { + dt = String(p.mysql.dataType); + } else if (p.dataType) { dt = String(p.dataType); } return dt; diff --git a/package.json b/package.json index 29b289e..27c6a38 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "async": "^0.9.0", "debug": "^2.1.1", + "lodash": "^4.17.4", "loopback-connector": "^4.0.0", "mysql": "^2.11.1", "strong-globalize": "^2.5.8" diff --git a/test/datatypes.test.js b/test/datatypes.test.js index 63d40c3..24dd4bf 100644 --- a/test/datatypes.test.js +++ b/test/datatypes.test.js @@ -6,13 +6,106 @@ 'use strict'; require('./init.js'); var assert = require('assert'); +var _ = require('lodash'); -var db, BlobModel, EnumModel, ANIMAL_ENUM; +var db, BlobModel, EnumModel, ANIMAL_ENUM, City, Account; var mysqlVersion; describe('MySQL specific datatypes', function() { before(setup); + describe('Support explicit datatypes on a property', function() { + var dateString1 = '2017-04-01'; + var dateString2 = '2016-01-30'; + var dateForTransactions = [new Date(dateString1).toString(), new Date(dateString2).toString()]; + var data = [ + { + type: 'Student - Basic', + amount: 1000, + lastTransaction: dateString1, + }, + { + type: 'Professional', + amount: 1999.99, + lastTransaction: dateString2, + }, + ]; + before(function(done) { + require('./init.js'); + db = getSchema(); + Account = db.define('Account', { + type: {type: String}, + amount: { + type: Number, + mysql: { + dataType: 'DECIMAL', + dataPrecision: 10, + dataScale: 2, + }, + }, + lastTransaction: { + type: String, + mysql: { + dataType: 'DATE', + }, + }, + }); + db.automigrate(done); + }); + after(function(done) { + Account.destroyAll(done); + }); + + it('create an instance', function(done) { + Account.create(data, function(err, result) { + assert(!err); + assert(result); + assert(_.isEqual(data.length, result.length)); + assert(_.isEqual(data[0].amount, result[0].amount)); + assert(_.isEqual(data[1].amount, result[1].amount)); + done(); + }); + }); + + it('find an instance', function(done) { + Account.find(function(err, result) { + assert(!err); + assert(result); + assert(_.isEqual(data.length, result.length)); + assert(_.isEqual(data[0].amount, result[0].amount)); + assert(_.isEqual(data[1].amount, result[1].amount)); + assert(_.isEqual(dateForTransactions[0], result[0].lastTransaction)); + assert(_.isEqual(dateForTransactions[1], result[1].lastTransaction)); + done(); + }); + }); + + it('find an instance by id', function(done) { + Account.findById(1, function(err, result) { + assert(!err); + assert(result); + assert(_.isEqual(data[0].amount, result.amount)); + assert(_.isEqual(dateForTransactions[0], result.lastTransaction)); + done(); + }); + }); + + it('update an instance', function(done) { + var updatedData = { + type: 'Student - Basic', + amount: 1155.77, + users: {}, + }; + Account.update({id: 1}, updatedData, function(err, result) { + assert(!err); + assert(result); + assert(result.count); + assert.equal(1, result.count); + done(); + }); + }); + }); + it('should run migration', function(done) { db.automigrate(function() { done();