Use MySQL DEFAULT Clause/Constant (#319)
* Adding ability to use MySQL DEFAULT clause Adding mysql.default option and documentation on special case for date. Adding unit tests for Default Clause. * Handle unsupported types, don't stringify numbers * Adding note about unsupported column types. * Update readme.
This commit is contained in:
parent
ccac704cce
commit
99597460f0
31
README.md
31
README.md
|
@ -258,6 +258,37 @@ Use the `limit` option to alter the display width. Example:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Default Clause/Constant
|
||||||
|
Use the `default` property to have MySQL handle setting column `DEFAULT` value.
|
||||||
|
```javascript
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"mysql": {
|
||||||
|
"default": "pending"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"type": "number",
|
||||||
|
"mysql": {
|
||||||
|
"default": 256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
For the date or timestamp types use `CURRENT_TIMESTAMP` or `now`:
|
||||||
|
```javascript
|
||||||
|
"last_modified": {
|
||||||
|
"type": "date",
|
||||||
|
"mysql": {
|
||||||
|
"default":"CURRENT_TIMESTAMP"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**NOTE**: The following column types do **NOT** supported [MySQL Default Values](https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html):
|
||||||
|
- BLOB
|
||||||
|
- TEXT
|
||||||
|
- GEOMETRY
|
||||||
|
- JSON
|
||||||
|
|
||||||
### Floating-point types
|
### Floating-point types
|
||||||
|
|
||||||
For Float and Double data types, use the `precision` and `scale` options to specify custom precision. Default is (16,8). For example:
|
For Float and Double data types, use the `precision` and `scale` options to specify custom precision. Default is (16,8). For example:
|
||||||
|
|
|
@ -701,7 +701,7 @@ function mixinMigration(MySQL, mysql) {
|
||||||
var p = this.getModelDefinition(model).properties[prop];
|
var p = this.getModelDefinition(model).properties[prop];
|
||||||
var line = this.columnDataType(model, prop) + ' ' +
|
var line = this.columnDataType(model, prop) + ' ' +
|
||||||
(this.isNullable(p) ? 'NULL' : 'NOT NULL');
|
(this.isNullable(p) ? 'NULL' : 'NOT NULL');
|
||||||
return line;
|
return columnDefault(p, line);
|
||||||
};
|
};
|
||||||
|
|
||||||
// override this function from base connector to allow mysql connector to
|
// override this function from base connector to allow mysql connector to
|
||||||
|
@ -770,6 +770,28 @@ function mixinMigration(MySQL, mysql) {
|
||||||
return dt;
|
return dt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function columnDefault(p, line) {
|
||||||
|
if (typeof p.type === 'undefined' || typeof p.type.name !== 'string') {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
// Unsupported column types
|
||||||
|
if (['blob', 'json', 'text'].indexOf(p.type.name.toLowerCase()) !== -1) {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
if (typeof p.mysql !== 'undefined' && p.mysql.default) {
|
||||||
|
var columnDefault = p.mysql.default;
|
||||||
|
if (typeof columnDefault === 'number') {
|
||||||
|
return line + ' DEFAULT ' + columnDefault;
|
||||||
|
}
|
||||||
|
if (typeof columnDefault === 'string') {
|
||||||
|
return line + ' DEFAULT ' +
|
||||||
|
(columnDefault.toUpperCase() === 'CURRENT_TIMESTAMP' || columnDefault.toLowerCase() === 'now' ?
|
||||||
|
'CURRENT_TIMESTAMP' : '"' + columnDefault + '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
function columnType(p, defaultType) {
|
function columnType(p, defaultType) {
|
||||||
var dt = defaultType;
|
var dt = defaultType;
|
||||||
if (p.mysql && p.mysql.dataType) {
|
if (p.mysql && p.mysql.dataType) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ var platform = require('./helpers/platform');
|
||||||
var should = require('./init');
|
var should = require('./init');
|
||||||
var Schema = require('loopback-datasource-juggler').Schema;
|
var Schema = require('loopback-datasource-juggler').Schema;
|
||||||
|
|
||||||
var db, UserData, StringData, NumberData, DateData, SimpleEmployee;
|
var db, UserData, StringData, NumberData, DateData, DefaultData, SimpleEmployee;
|
||||||
var mysqlVersion;
|
var mysqlVersion;
|
||||||
|
|
||||||
describe('migrations', function() {
|
describe('migrations', function() {
|
||||||
|
@ -373,6 +373,84 @@ describe('migrations', function() {
|
||||||
], done);
|
], done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should take on database default CURRENT_TIMESTAMP, boolean 0 and pending string for columns', function(done) {
|
||||||
|
DefaultData.create({}, function(err, obj) {
|
||||||
|
assert.ok(!err);
|
||||||
|
assert.ok(obj);
|
||||||
|
var now = new Date();
|
||||||
|
DefaultData.findById(obj.id, function(err, found) {
|
||||||
|
now.setSeconds(0);
|
||||||
|
found.dateTime.setSeconds(0);
|
||||||
|
found.timestamp.setSeconds(0);
|
||||||
|
|
||||||
|
assert.equal(found.dateTime.toGMTString(), now.toGMTString());
|
||||||
|
assert.equal(found.timestamp.toGMTString(), now.toGMTString());
|
||||||
|
assert.equal(found.isAdmin, '0');
|
||||||
|
assert.equal(found.number, 256);
|
||||||
|
assert.equal(found.data, null);
|
||||||
|
assert.equal(found.text, null);
|
||||||
|
assert.equal(found.status, 'pending');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('DefaultData should have correct columns', function(done) {
|
||||||
|
getFields('DefaultData', function(err, fields) {
|
||||||
|
fields.should.be.eql({
|
||||||
|
id: {Field: 'id',
|
||||||
|
Type: 'int(11)',
|
||||||
|
Null: 'NO',
|
||||||
|
Key: 'PRI',
|
||||||
|
Default: null,
|
||||||
|
Extra: 'auto_increment'},
|
||||||
|
dateTime: {Field: 'dateTime',
|
||||||
|
Type: 'datetime',
|
||||||
|
Null: 'YES',
|
||||||
|
Key: '',
|
||||||
|
Default: 'CURRENT_TIMESTAMP',
|
||||||
|
Extra: ''},
|
||||||
|
timestamp: {Field: 'timestamp',
|
||||||
|
Type: 'timestamp',
|
||||||
|
Null: 'YES',
|
||||||
|
Key: '',
|
||||||
|
Default: 'CURRENT_TIMESTAMP',
|
||||||
|
Extra: ''},
|
||||||
|
isAdmin: {Field: 'isAdmin',
|
||||||
|
Type: 'tinyint(1)',
|
||||||
|
Null: 'YES',
|
||||||
|
Key: '',
|
||||||
|
Default: '0',
|
||||||
|
Extra: ''},
|
||||||
|
number: {Field: 'number',
|
||||||
|
Type: 'int(10) unsigned',
|
||||||
|
Null: 'NO',
|
||||||
|
Key: 'MUL',
|
||||||
|
Default: '256',
|
||||||
|
Extra: ''},
|
||||||
|
data: {Field: 'data',
|
||||||
|
Type: 'longtext',
|
||||||
|
Null: 'YES',
|
||||||
|
Key: '',
|
||||||
|
Default: null,
|
||||||
|
Extra: ''},
|
||||||
|
text: {Field: 'text',
|
||||||
|
Type: 'varchar(1024)',
|
||||||
|
Null: 'YES',
|
||||||
|
Key: '',
|
||||||
|
Default: null,
|
||||||
|
Extra: ''},
|
||||||
|
status: {Field: 'status',
|
||||||
|
Type: 'varchar(512)',
|
||||||
|
Null: 'YES',
|
||||||
|
Key: '',
|
||||||
|
Default: 'pending',
|
||||||
|
Extra: ''},
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should allow both kinds of date columns', function(done) {
|
it('should allow both kinds of date columns', function(done) {
|
||||||
DateData.create({
|
DateData.create({
|
||||||
dateTime: new Date('Aug 9 1996 07:47:33 GMT'),
|
dateTime: new Date('Aug 9 1996 07:47:33 GMT'),
|
||||||
|
@ -503,6 +581,17 @@ function setup(done) {
|
||||||
floater: {type: Number, dataType: 'double', precision: 14, scale: 6},
|
floater: {type: Number, dataType: 'double', precision: 14, scale: 6},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DefaultData = db.define('DefaultData', {
|
||||||
|
dateTime: {type: Date, dataType: 'datetime', mysql: {default: 'now'}},
|
||||||
|
timestamp: {type: Date, dataType: 'timestamp', mysql: {default: 'CURRENT_TIMESTAMP'}},
|
||||||
|
isAdmin: {type: Boolean, mysql: {default: '0'}},
|
||||||
|
number: {type: Number, null: false, index: true, unsigned: true,
|
||||||
|
dataType: 'int', mysql: {default: 256}},
|
||||||
|
data: {type: Schema.JSON, dataType: 'longText', mysql: {default: 'Not Supported'}},
|
||||||
|
text: {type: Schema.Text, dataType: 'varchar', limit: 1024, mysql: {default: 'Not Supported'}},
|
||||||
|
status: {type: String, dataType: 'varchar', mysql: {default: 'pending'}},
|
||||||
|
});
|
||||||
|
|
||||||
DateData = db.define('DateData', {
|
DateData = db.define('DateData', {
|
||||||
dateTime: {type: Date, dataType: 'datetime'},
|
dateTime: {type: Date, dataType: 'datetime'},
|
||||||
timestamp: {type: Date, dataType: 'timestamp'},
|
timestamp: {type: Date, dataType: 'timestamp'},
|
||||||
|
|
Loading…
Reference in New Issue