Skip to content

Log a warning when type: 'number' is used with certain large numeric column types. #272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions helpers/private/query/process-each-record.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ module.exports = function processEachRecord(options) {

// Run all the records through the iterator so that they can be normalized.
eachRecordDeep(options.records, function iterator(record, WLModel) {
// Check if the record and the model contain auto timestamps and make
// sure that if they are type number that they are actually numbers and
// not strings.
// We're forced to store JS timestamps in BIGINT columns b/c they are too big for
// regular INT columns, but BIGINT can potentially be larger than the JS
// max int so Postgresql automatically transforms it to a string. If the user
// declared them with `type: 'number'`, we'll transform them back to numbers here.
_.each(WLModel.definition, function checkAttributes(attrVal) {
var columnName = attrVal.columnName;

Expand Down
27 changes: 22 additions & 5 deletions helpers/register-data-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,33 @@ module.exports = require('machine').build({
return exits.badConfiguration(new Error('Connection config is missing a database value.'));
}

// Loop through every model assigned to the datastore we're registering,
// and ensure that each one's primary key is either required or auto-incrementing.
// Loop through every model assigned to the datastore we're registering.
try {
_.each(inputs.models, function checkPrimaryKey(modelDef, modelIdentity) {
var primaryKeyAttr = modelDef.definition[modelDef.primaryKey];
_.each(inputs.models, function checkModel(modelDef, modelIdentity) {

// Ensure that the model's primary key has either `autoIncrement` or `required`
// Ensure that the primary key is either required or auto-incrementing.
var primaryKeyAttr = modelDef.definition[modelDef.primaryKey];
if (primaryKeyAttr.required !== true && (!primaryKeyAttr.autoMigrations || primaryKeyAttr.autoMigrations.autoIncrement !== true)) {
throw new Error('In model `' + modelIdentity + '`, primary key `' + modelDef.primaryKey + '` must have either `required` or `autoIncrement` set.');
}

// Loop through each attribute in the model.
_.each(modelDef.definition, function(attribute, attributeName) {
// If the column type is 'bigint', 'decimal', 'numeric' or 'bigserial',
// and the attribute type is not 'string', log a warning. The Postgresql
// driver will always return data from these columns as strings because
// they may be too big to fit in a JavaScript integer.
//
// Skip this check for `autoCreatedAt` and `autoUpdatedAt` attributes, which are transformed
// into numbers internally if the `type` is 'number'.
if (attribute.autoCreatedAt || attribute.autoUpdatedAt) { return; }
if (attribute.autoMigrations && _.contains(['bigint', 'decimal', 'numeric', 'bigserial'], attribute.autoMigrations.columnType) && attribute.type !== 'string') {
console.log('In attribute `' + attributeName + '` of model `' + modelIdentity + '`:');
console.log('When `columnType` is set to `' + attribute.autoMigrations.columnType + '`, `type` should be set to `string` in order to avoid a loss in precision.');
console.log();
}
});

});
} catch (e) {
return exits.badConfiguration(e);
Expand Down