Add a new property option `defaultFn`

The property allows developers to specify that the default value
should be retrieved via a named function.

Only two built-in functions are supported at the moment:

  "guid", "uuid" - generate a new GUID/UUID
  "now" - use the current date and time

Support for custom (user-provided) functions is not implemented yet.
This commit is contained in:
Miroslav Bajtoš 2015-02-20 11:18:47 +01:00
parent c939efe1e7
commit ba0f3c1616
3 changed files with 65 additions and 1 deletions

View File

@ -16,6 +16,7 @@ var validations = require('./validations');
var _extend = util._extend; var _extend = util._extend;
var utils = require('./utils'); var utils = require('./utils');
var fieldsToArray = utils.fieldsToArray; var fieldsToArray = utils.fieldsToArray;
var uuid = require('node-uuid');
// Set up an object for quick lookup // Set up an object for quick lookup
var BASE_TYPES = { var BASE_TYPES = {
@ -228,10 +229,34 @@ ModelBaseClass.prototype._initProperties = function (data, options) {
} }
// FIXME: We should coerce the value // FIXME: We should coerce the value
// will implement it after we refactor the PropertyDefinition // will implement it after we refactor the PropertyDefinition
self.__data[p] = def; self.__data[p] = propVal = def;
} }
} }
// Set default value using a named function
if (propVal === undefined) {
var defn = properties[p].defaultFn;
switch (defn) {
case undefined:
break;
case 'guid':
case 'uuid':
// Generate a v1 (time-based) id
propVal = uuid.v1();
break;
case 'now':
propVal = new Date();
break;
default:
// TODO Support user-provided functions via a registry of functions
console.warn('Unknown default value provider ' + defn);
}
// FIXME: We should coerce the value
// will implement it after we refactor the PropertyDefinition
if (propVal !== undefined)
self.__data[p] = propVal;
}
// Handle complex types (JSON/Object) // Handle complex types (JSON/Object)
if (!BASE_TYPES[type.name]) { if (!BASE_TYPES[type.name]) {

View File

@ -33,6 +33,7 @@
"inflection": "^1.6.0", "inflection": "^1.6.0",
"lodash": "~3.0.1", "lodash": "~3.0.1",
"loopback-connector": "1.x", "loopback-connector": "1.x",
"node-uuid": "^1.4.2",
"qs": "^2.3.3", "qs": "^2.3.3",
"traverse": "^0.6.6" "traverse": "^0.6.6"
}, },

View File

@ -4,6 +4,8 @@ var should = require('./init.js');
var db, Person; var db, Person;
var ValidationError = require('..').ValidationError; var ValidationError = require('..').ValidationError;
var UUID_REGEXP = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
describe('manipulation', function () { describe('manipulation', function () {
before(function (done) { before(function (done) {
@ -471,6 +473,42 @@ describe('manipulation', function () {
done(); done();
}); });
it('should generate a new id when "defaultFn" is "guid"', function (done) {
var CustomModel = db.define('CustomModel', {
guid: { type: String, defaultFn: 'guid' }
});
var inst = CustomModel.create(function (err, m) {
m.guid.should.match(UUID_REGEXP);
done();
});
});
it('should generate a new id when "defaultfn" is "uuid"', function (done) {
var CustomModel = db.define('custommodel', {
guid: { type: String, defaultFn: 'uuid' }
});
var inst = CustomModel.create(function (err, m) {
m.guid.should.match(UUID_REGEXP);
done();
});
});
it('should generate current time when "defaultFn" is "now"', function (done) {
var CustomModel = db.define('CustomModel', {
now: { type: Date, defaultFn: 'now' }
});
var now = Date.now();
var inst = CustomModel.create(function (err, m) {
m.now.should.be.instanceOf(Date);
m.now.should.be.within(now, now + 200);
done();
});
});
// it('should work when constructor called as function', function() { // it('should work when constructor called as function', function() {
// var p = Person({name: 'John Resig'}); // var p = Person({name: 'John Resig'});
// p.should.be.an.instanceOf(Person); // p.should.be.an.instanceOf(Person);